Связывание зависит от типа элемента - PullRequest
0 голосов
/ 01 января 2012

Как я могу изменить связанное значение в зависимости от типа связанного элемента.

Я использую TreeListView из Кристиана Риччоло , хотя он работает точно так же со стандартным TreeView.

У меня есть два класса

class Group
{
  public String Name {get;}
  public Int32 MaxItems {get;}
  public ObservableList<Item> Items {get;}
}

class Item
{
  public String Name {get;}
  public String Status {get;}
}

XAML

<Grid>
  <r:TreeListView ItemsSource="{Binding}">
    <r:TreeListView.Resources>
      <HierarchicalDataTemplate DataType="{x:Type local:Group}" ItemsSource="{Binding Items}" />
      <DataTemplate DataType="{x:Type local:Item}" />
    </r:TreeListView.Resources>
    <r:TreeListView.Columns>
      <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}"  />
      <GridViewColumn Header="Status" DisplayMemberBinding="???" />
    </r:TreeListView.Columns>
  </r:TreeListView>
</Grid>

Это прекрасно работает, и я вижу все группы и их элементы.

В столбце состояния я хочу отобразить Item.Status и Group.Items.Count +"/"+ MaxItems в зависимости от того, что на самом деле отображается в этой строке.

В настоящее время я использую {Binding Converter={StaticResource testConverter}}, где testConverter генерирует вывод в зависимости от типа, но это громоздко, и я надеюсь, что есть более чистый способ.

Я не могу / не хочу создавать свойство Group.Status. Я думаю, что я также не могу использовать a в шаблонах данных, так как DisplayMemberBinding перезаписывает их, и я хочу иметь возможность сделать это с несколькими столбцами / привязками.

1 Ответ

2 голосов
/ 01 января 2012

Единственный способ, с которым я до сих пор сталкивался, - это использование CellTemplateSelector свойства GridViewColumn.Вам нужно будет ввести DataTemplateSelector, чтобы выбрать правильный DataTemplate.Это немного чище в том смысле, что вы по-прежнему определяете макет / содержимое дисплея в xaml и просто выбираете соответствующий шаблон.

Редактировать : Да, вы не можете использовать DisplayMemberBinding в этом случае, однако, DisplayMemberBinding - это простой ярлык для шаблона данных TextBlock, привязанного к пути.Однако, когда вы используете табличку с данными, вы можете выполнить там все необходимые привязки - в этом случае вам не понадобится DisplayMemberBinding.

Быстрый пример:

<Grid>
    <Grid.Resources>
        <r:NameCellTemplateSelector x:Key="NameTemplateSelector"/>
        <r:StatusCellTemplateSelector x:Key="StatusTemplateSelector"/>
    <Grid.Resources>

    ...

    <GridViewColumn Header="Name" CellTemplateSelector={StaticResource NameTemplateSelector}  />
    <GridViewColumn Header="Status" CellTemplateSelector={StaticResource StatusTemplateSelector} />
</Grid>

И иреализовать селекторы:

public class NameCellTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        // find the data template with a specific x:Key
        return element.FindResource("someNameTemplate") as DataTemplate;
    }
}

public class StatusCellTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        FrameworkElement element = container as FrameworkElement;

        // find the data template with a specific x:Key
        return element.FindResource("someStatusCellTemplate") as DataTemplate;
    }
}

Возможно, вам также может потребоваться просто написать один селектор, поскольку параметр container является элементом пользовательского интерфейса, и вы можете пройтись по визуальному дереву, чтобы выяснить, к какому столбцу относится селектор.быть призванным и выбирать соответствующим образом исходя из этого.См. Также ответы на этот вопрос: Передача данных в селектор шаблонов данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...