使用datatemplates转换项目源

时间:2015-02-10 10:49:04

标签: c# wpf xaml mvvm data-binding

假设我有ItemsControl用于呈现viewModel列表的按钮

  <ItemsControl ItemsSource="{Binding PageViewModelTypes}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Content="{Binding Name}" 
                        CommandParameter="{Binding }" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

PageViewModelTypes是可用的视图模型(例如OtherViewModel)。对于每种类型,都有一个DataTemplate设置,其中包含相应的视图。

<dx:DXWindow.Resources>
    <DataTemplate DataType="{x:Type generalDataViewModel:GeneralViewModel}">
        <generalDataViewModel:GeneralView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type other:OtherViewModel}">
        <other:OtherView />
    </DataTemplate>
</dx:DXWindow.Resources>

有没有办法用视图中PageViewModelTypes的相应模板类型替换ItemsControl

2 个答案:

答案 0 :(得分:1)

将按钮内容绑定到项目内容,您的模板将被解析为实际类型:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Button Content="{Binding}" 
                CommandParameter="{Binding }" />
    </DataTemplate>
</ItemsControl.ItemTemplate>

答案 1 :(得分:0)

不幸的是,你的问题一点也不清楚。最常见的情况可能符合您提供的模糊描述,即使用与该类型对应的ItemsControl显示DataTemplate中的每个项目。

让我们称之为Option A

但声明:

  

PageViewModelTypes替换为视图中ItemsControl的相应模板类型

...可以解释为您需要一个完全不同的控件数据源。即您希望有选择地为ItemsSource属性选择不同的值。

让我们称之为Option B

然后,在评论中,有人问你:

  

当用户点击相关按钮时,是否要显示模板?

...你回答了#34;是的&#34;!尽管这与上述两种情况完全不同。

让我们称之为Option C

也许我们可以鼓励您提供急需的澄清。但要做到这一点,从最简单,最常见的情景开始似乎最有成效。以下是实现Option A的代码示例:

<强> XAML:

<Window x:Class="TestSO28429768ButtonTemplate.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestSO28429768ButtonTemplate"
        Title="MainWindow" Height="350" Width="525">

  <Window.Resources>
    <local:ColorToBrushConverter x:Key="colorToBrushConverter1"/>
    <local:BaseViewModelCollection x:Key="itemsCollection">
      <local:StringViewModel Text="Foo"/>
      <local:StringViewModel Text="Bar"/>
      <local:ColorViewModel Color="Yellow"/>
      <local:ColorViewModel Color="LightBlue"/>  
    </local:BaseViewModelCollection>

    <DataTemplate DataType="{x:Type local:StringViewModel}">
      <TextBlock Text="{Binding Text}"/>
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:ColorViewModel}">
      <Rectangle Width="50" Height="25"
                 Fill="{Binding Path=Color, Converter={StaticResource colorToBrushConverter1}}" />
    </DataTemplate>
  </Window.Resources>

  <Grid>
    <ItemsControl ItemsSource="{StaticResource itemsCollection}">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <Button Content="{Binding}"/>
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>
  </Grid>
</Window>

<强> C#:

class BaseViewModelCollection : List<BaseViewModel> { }

class BaseViewModel { }

class StringViewModel : BaseViewModel
{
    public string Text { get; set; }
}

class ColorViewModel : BaseViewModel
{
    public Color Color { get; set; }
}

class ColorToBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return new SolidColorBrush((Color)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
}

正如您所见,ItemsControl使用其默认面板Button显示StackPanel个实例。每个Content的{​​{1}}绑定到Button集合中的相应项目,该列表包含ItemsSource类和StringViewModel类中的每一个。

通过窗口资源中定义的模板,按钮的内容展示者使用与每种视图模型相关联的ColorViewModel。与DataTemplate对应的项目获取该类型的模板,即显示视图模型文本的StringViewModel。同样,与TextBlock实例对应的项目将获得显示填充了视图模型中颜色的矩形的模板。

如果以上未完全解决您的问题(并且可能不会),请编辑您的问题以澄清您的要求:

  • 如果上述情况接近,但并不完全符合您的要求,请使用上述内容作为参考,并解释您想要做的事情与众不同。
  • 如果上述内容与您想要的内容无关,请忽略它。但是具体关于你真正想要的东西,并使用精确的术语。例如,如果你真的想用另一个集合替换 ColorViewModel,那么说你想要替换ItemsSource集合是有意义的。但如果没有,不要使用一个似乎正好说出来的短语!

当然,如果PageViewModelTypesOption B更接近您要尝试的内容,请继续使用这些作为您的说明的参考。

最后,请查看非常有用的网页How do I ask a good question?How to create a Minimal, Complete, and Verifiable example。他们有很多很好的信息,告诉你如何以一种让别人轻易理解你的意思的方式来表达自己。 :)