绑定取决于项目类型

时间:2012-01-01 19:32:17

标签: c# wpf xaml data-binding

如何根据绑定项的类型更改边界值。

我正在使用Christian Ricciolo中的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.StatusGroup.Items.Count +"/"+ MaxItems,具体取决于该行中实际显示的内容。

目前我正在使用{Binding Converter={StaticResource testConverter}},其中testConverter根据类型生成输出,但这很麻烦,我希望有更清洁的方法。

我不能/不想创建Group.Status属性。 我想我也不能在数据模板中使用a,因为DisplayMemberBinding会覆盖它们,我希望能够用多个列/绑定来做到这一点。

1 个答案:

答案 0 :(得分:2)

到目前为止,我遇到的另一种方法是使用GridViewColumn的{​​{3}}属性。您需要实施CellTemplateSelector来选择正确的DataTemplate。从某种意义上说,你仍然可以定义xaml中的显示布局/内容,只需选择合适的模板。

修改:是的,在这种情况下您无法使用DisplayMemberBinding,但DisplayMemberBinding是绑定到TextBlock数据模板的简单快捷方式路径。但是,当您使用datatemplate时,您可以在那里执行所需的所有绑定 - 在这种情况下您不需要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参数是UI元素,你可以走可视树,找出选择器被调用的列,并根据那。另请参阅此问题的答案:DataTemplateSelector