为相同的源定义不同的DataTemplate

时间:2014-04-02 10:18:22

标签: c# wpf wpf-4.0

我正在尝试用ListView的DataTemplate显示bool的集合。 这是代码:

在MainWindow.xaml

<Window.Resources>       
    <DataTemplate x:Key="ListItemCheckBoxTemplate">
        <CheckBox IsChecked="{Binding Mode=OneWay}"/>
    </DataTemplate>
    <DataTemplate x:Key="ListItemRadioButtonTemplate">
        <RadioButton IsChecked="{Binding Mode=OneWay}"/>
    </DataTemplate>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="120"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>        
    <TextBlock Text="ListViewSample" />
    <ListBox ItemsSource="{Binding MyData}" ItemTemplate="{StaticResource ListItemCheckBoxTemplate}" Grid.Column="1"/>                    
</Grid>

在MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();  
    }
}

public class ViewModel
{
    private List<bool> myBooleanCollection;
    public List<bool> MyData
    {
        get { return myBooleanCollection;  }
        set { myBooleanCollection = value; }
    }

    public ViewModel()
    {
        myBooleanCollection = new List<bool>();
        myBooleanCollection.Add(true);
        myBooleanCollection.Add(false);
        myBooleanCollection.Add(true);
        myBooleanCollection.Add(true);
        myBooleanCollection.Add(false);            
    }
}

而不是ItemTemplate ListItemCheckBoxTemplate我想用单选按钮应用ListItemRadioButtonTemplate。我如何在xaml中为同一个源指定ItemTemplate的使用。我是否需要更改相同的数据源或 我是否有办法根据条件在xaml中指定DataTemplate。

3 个答案:

答案 0 :(得分:2)

您没有指定要更改模板的条件,但您可以向视图模型中添加其他属性,例如AllowMultiple

public class ViewModel: INotifyPropertyChanged
{
   private List<bool> myBooleanCollection;

   public List<bool> MyData
   {
      get { return myBooleanCollection;  }
      set { myBooleanCollection = value; }
   }

   private bool _allowMultiple;

   public bool AllowMultiple
   {
      get { return _allowMultiple; }
      set
      {
         if (_allowMultiple != value)
         {
            _allowMultiple = value;
            OnPropertyChanged("AllowMultiple");
         }
      }
   }
}

然后将ListBox.Style更改为:

<ListBox ItemsSource="{Binding MyData}">
   <ListBox.Style>
      <Style TargetType="{x:Type ListBox}">
         <Setter Property="ItemTemplate" Value="{StaticResource ListItemCheckBoxTemplate}"/>
         <Style.Triggers>
            <DataTrigger Binding="{Binding Path=AllowMultiple}" Value="False">
               <Setter Property="ItemTemplate" Value="{StaticResource ListItemRadioButtonTemplate}"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </ListBox.Style>
</ListBox>

假设ViewModel实施INotifyPropertyChanged,您可以根据视图模式更改ItemTemplate购买更改AllowMultiple

答案 1 :(得分:1)

您可以使用followign属性为每个项目指定DataTemplate:

ItemTemplate="{StaticResource ListItemCheckBoxTemplate}

将其更改为:

ItemTemplate="{StaticResource ListItemRadioButtonTemplate}

如果您需要在同一个ListBox中有多个项目模板,那么您可以通过DataTemplateSelector Class

提供自定义模板选择逻辑

如果要在Xaml中执行此操作,则需要公开可绑定到的属性作为选择器。看看A Data Template Selector in Xaml

答案 2 :(得分:0)

您需要创建DataTemplateSelector并将其用于ItemTemplateSelector。您还需要确定返回DataTemplate的条件。例如:

<强> XAML

<Window x:Class="YourNamespace.MainWindow" ...
        xmlns:this="clr-namespace:YourNamespace"

<Window.Resources>
    <DataTemplate x:Key="OneTemplate">
        <CheckBox IsChecked="{Binding Mode=OneWay}" />
    </DataTemplate>

    <DataTemplate x:Key="SecondTemplate">
        <RadioButton IsChecked="{Binding Mode=OneWay}" />
    </DataTemplate>
</Window.Resources>

<ListBox ItemsSource="{Binding MyData}">            
    <ListBox.ItemTemplateSelector>
        <this:MyItemTemplateSelector OneTemplate="{StaticResource OneTemplate}" 
                                     SecondTemplate="{StaticResource SecondTemplate}" />            
    </ListBox.ItemTemplateSelector>
</ListBox>

<强> Code-behind

public class MyItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate OneTemplate { get; set; }
    public DataTemplate SecondTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        bool myItem = (bool)item;

        if (myItem == true)
        {
            return OneTemplate;
        }

        return SecondTemplate;
    }
}