سؤال

I'm trying to show collection of bool with a DataTemplate for ListView. Here's the code:

In 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>

In 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);            
    }
}

Instead of ItemTemplate ListItemCheckBoxTemplate I want to apply ListItemRadioButtonTemplate with Radio button. How I can specify the use of ItemTemplate for the same source in xaml. Do I need to change the DataSource for the same or do I have some way to specify the DataTemplate in xaml based on condition.

هل كانت مفيدة؟

المحلول

You did not specify what is the condition on which you want to change template but you can add another property to your view model, say 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");
         }
      }
   }
}

and then change ListBox.Style to:

<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>

assuming that ViewModel implements INotifyPropertyChanged you can then change ItemTemplate buy changing AllowMultiple against view model

نصائح أخرى

You can specify DataTemplate for each item with the followign attribute:

ItemTemplate="{StaticResource ListItemCheckBoxTemplate}

Change this to:

ItemTemplate="{StaticResource ListItemRadioButtonTemplate}

If you need multiple item templates in the same ListBox then you can provide custom template selection logic via the DataTemplateSelector Class

If you want to do it in Xaml, you will need to expose property which you can bind to as a selector. Have a look at A Data Template Selector in Xaml

You need create DataTemplateSelector and using this for ItemTemplateSelector. You also need to determine the condition under which you will return the DataTemplate. Example:

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;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top