Bind data to different element based on function/content of the data - c#

While reading about the datatemplates I noticed you can choose different templates based on the type of data. - However can one also do this for different content of the data?
My modelview provides a list of data, in principle it's just a list of tuples (bound in a custom class to make typing easier) with Tuple<ImageData, AltText>.
The type of the property in the ModelView is:
ReadOnlyObservableCollection<ThumbDispData>
With ThumbDispData:
public class ThumbDispData
{
public ImageData Idhl { get; set; }
public string AltText { get; set; }
}
Now I wish to display an Image if it can (ImageData.Source is non null) - Otherwise it should show an alt-text.
The xaml or the usercontrol:
<UserControl x:Class="test.ThumbPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:test="clr-namespace:test"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<DataTemplate DataType="{x:Type test:ThumbDispData}">
<TextBlock Text="{Binding AltText}"></TextBlock>
</DataTemplate>
</UserControl.Resources>
<Grid Background="Transparent">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</UserControl>
Well above only shows the alt-text (which works): how would I create a selector based on the content of ThumbDispData.

You could use a DataTemplateSelector:
<UserControl.Resources>
<DataTemplate x:Key="tt" DataType="{x:Type test:ThumbDispData}">
<TextBlock Text="{Binding AltText}"></TextBlock>
</DataTemplate>
<DataTemplate x:Key="img" DataType="{x:Type test:ThumbDispData}">
<Image Source="{Binding Idhl}" />
</DataTemplate>
<local:Selector x:Key="selector" TextTemplate="{StaticResource tt}" ImageTemplate="{StaticResource img}" />
</UserControl.Resources>
<Grid Background="Transparent">
<ItemsControl ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource selector}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
public class Selector : DataTemplateSelector
{
public DataTemplate ImageTemplate { get; set; }
public DataTemplate TextTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
ThumbDispData data = item as ThumbDispData;
if (data != null && data.Idhl != null)
return ImageTemplate;
return TextTemplate;
}
}

would I create a selector based on the content of ThumbDispData.
You would typically write a subclass of DataTemplateSelector, in which you check the Idhl property and return a different template object depending on whether it's null or not. Typically, the template would be a resource, which you load dynamically in the selector.
But your scenario is simple enough that I would use styles instead. For example:
<DataTemplate DataType="{x:Type test:ThumbDispData}"
xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Grid>
<TextBlock Text="{Binding AltText}">
<TextBlock.Style>
<p:Style TargetType="TextBlock">
<Setter Visibility="Visible"/>
<p:Style.Triggers>
<DataTrigger Binding="{Binding Idhl}" Value="{x:Null}">
<Setter Visibility="Collapsed"/>
</DataTrigger>
</p:Style>
</p:Style>
</TextBlock.Style>
</TextBlock>
<Image Source="{Binding Idhl}">
<Image.Style>
<p:Style TargetType="Image">
<Setter Visibility="Collapsed"/>
<p:Style.Triggers>
<DataTrigger Binding="{Binding Idhl}" Value="{x:Null}">
<Setter Visibility="Visible"/>
</DataTrigger>
</p:Style>
</p:Style>
</Image.Style>
</Image>
</Grid>
</DataTemplate>
Notes:
Strictly speaking, you don't need the <Setter Visibility="Visible"/> in the TextBlock style, since that's the default value. I put it there because it helps document the symmetry between the styles of the two elements.
The xmlns:p declaration is there only as a Stack Overflow work-around, because the XML formatter doesn't handle the XAML Style element correctly otherwise. In real XAML, you can leave that out and just use the Style name directly instead of p:Style.

Related

How to set template for listbox in WPF(Windows 10 Weather)

I am trying to create a Windows 10 weather application in WPF using C#. I need to have a Listbox to display recent 10 day weather section. I must set template for Listbox items. I tried this:
<ListBox Grid.Row="1" x:Name="DailyWeatherListBox">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel>
<!--...-->
</StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
This is the recent 10 day weather section (Windows 10 Weather)
Look the Windows 10 Weather. I put this image for disuse Windows 10.
I also don't know how to set Scrollbar in the Listbox corners. I would be very thankful if you could help.
I would start off something like this:
<ListBox ItemsSource="{Binding WeeklyWeather}"
SelectedItem="{Binding SelectedDailyWeather, Mode=TwoWay}">
//Use ItemTemplate to set how item looks "inside"
//I'll leave design details for you
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Day}"/>
<Image Source={Binding WheatherPicturePath}/>
<TextBlock Text="{Binding Temperature}"/>
<TextBlock Text="{Binding Description}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
//ItemsPanel defines container for items. It can be StackPanel, Wrapanel, Grid, etc
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
//You use this place to design how container normally looks like
<Border Background="White">
//DataTemplate defined above is placed in ContentPresenter
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
//Here we catch "IsSelected" event and re-design our template to visually reflect "selected"
<Trigger Property="IsSelected" Value="true">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Background="Gray">
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Here are couple ideas how for those bindings.
public class WeatherViewModel
{
public string Day { get; set; }
public string WheatherPicturePath { get; set; }
public string Temperature { get; set; }
public string Description { get; set; }
}
public class BindedDataContext
{
public ObservableCollection<WeatherViewModel> WeeklyWeather { get; set; }
public WeatherViewModel SelectedDailyWeather { get; set; }
//...
}
Your approaches for code-behind may differ, but they need to be in place for you to use those bindings.
For such scrollbar I would look into Change scrollviewer template in listbox
You can set a simple ListBox template like this:
<ListBox Grid.Row="1" x:Name="DailyWeatherListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<!--Insert XAML for One Item-->
<Label Content="{Binding}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBoxItem>Item 1</ListBoxItem>
<ListBoxItem>Item 2</ListBoxItem>
</ListBox>
In most real world scenarios where there is more then once piece of information per item to be displayed you would define how you want your data to be displayed through a DataTemplate. For example if I wanted to display both the high temperature and the low temperature and style them separately: I would first create a DailyWeather model in c# and create a DataTemplate for it, like so:
public class DailyWeather
{
public int High { get; set; }
public int Low { get; set; }
// You Would Add All Your Other Data You Want to Display Here
}
In your page resources (or another resource dictionary like in App.xaml):
<Window.Resources>
<DataTemplate DataType="{x:Type DailyWeather}">
<Grid>
<StackPanel>
<Label FontSize="18" Content="{Binding High}"/>
<Label FontSize="14" Content="{Binding Low}"/>
</StackPanel>
</Grid>
</DataTemplate>
</Window.Resources>
On your ListBox no ItemTemplate is required ...
<ListBox Grid.Row="1" x:Name="DailyWeatherListBox"/>
... because once you set the source to a List<DailyWeather>, (or do a binding like Siim Haas's answer suggests) your program will find the DataTemplate we defined for a DailyWeather object that we included in the resources.

XAML Design Data and StaticResources / CollectionViews

I've been using design time XAML data for a few weeks now and it seems to work fine except for some cases such as the current one where I want a listbox to display items based on a collection view declared as a resource.
Basically I want to display a list of "Things" grouped by Category.
public class Thing
{
public string Category { get; set; }
public string Name { get; set; }
}
And then I expose this via a dummy class ListOfThings
public class ListOfThings
{
public string ListName { get; set; }
public ObservableCollection<Thing> Things { get; set; }
}
I have a dummy XAML file for the data as follows (XMLFile1.xaml)
<local:ListOfThings xmlns:local="clr-namespace:ListBoxGroupExample"
ListName="TheListOfThings">
<local:ListOfThings.Things>
<local:Thing Name="Item1" Category="Catagory1" />
<local:Thing Name="Item2" Category="Catagory1" />
<local:Thing Name="Item3" Category="Catagory2" />
</local:ListOfThings.Things>
In the window I have a listbox with a group style for an expander for each group
<Window x:Class="ListBoxGroupExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ListBoxGroupExample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="525"
Height="350"
d:DataContext="{d:DesignData Source=/DesignData/XMLFile1.xaml}"
mc:Ignorable="d">
<Window.Resources>
<CollectionViewSource x:Key="GroupedData" Source="{Binding Path=Things}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Category" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<Grid>
<StackPanel>
<ListBox ItemsSource="{Binding Source={StaticResource GroupedData}}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" />
</Expander.Header>
<ItemsPresenter Margin="5,0,0,0" />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListBox.GroupStyle>
</ListBox>
</StackPanel>
</Grid>
This works at run time (I create an instance of ListOfThings, populate the Observable collection to have the same structure as the XAML design data) but at design time I get nothing.
If I change the ItemSource to directly bind to the ObservableCollection of Things rather than the collection view, it works but of course I get no grouping.
ItemsSource="{Binding Path=Things}"
Am I misunderstanding something with static resources in that they are not available at design time? Hence why the binding to the collectionview does not render?
Or is the binding syntax to Source incorrect?
Appears to work in Visual Studio/Blend 2013:

WPF Treeview HierarchicalDataTemplate ItemTemplateSelector

I am trying to create a simple 2 level Treeview in WPF (MVVM approach). For my first level I have a standard datatemplate, for my second level I want to use a Template Selector so that I can change the appearance of each item based on one of its properties.
Below is my Treeview xaml
<Treeview ItemsSource={Binding ListA}>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ListB}" ItemTemplateSelector={StaticResource TemplateSelector}>
<Textblock Text={Binding Name}/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
My first level is
<Textblock Text={Binding Name}/>
will just display a name
For my second level the TemplateSelector is returning a datatemplate which is something like
<DataTemplate x:Key="SomeKey">
<StackPanel Orientation="Horizontal">
<ViewBox>
-----
</ViewBox>
<TextBlock Text={Binding Name}/>
</StackPanel>
</DataTemplate>
But all I see for my second level is my second level ViewModel name. I double checked the template selector and it is definitely returning the correct data template but it is just not getting displayed.
Can anyone please point me in the right direction?
Edit -- Added more code as per request
this is my template selector
public class DataFieldsDataTemplateSelector : DataTemplateSelector
{
public DataTemplate AlphaTemplate { get; set; }
public ------
public ------
public DataFieldsDataTemplateSelector()
{
//This is getting the template from my ResourceDictionary
AlphaTemplate = (DataTemplate)dDictionary["alphaTemplate"];
}
public override DataTemplate SelectTemplate(object item,DependencyObject container)
{
//Somecode
return AlphaTemplate;
}
}
my template for AlphaTemplate in my dictionary is
<DataTemplate x:Key="alphaTemplate">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Viewbox IsHitTestVisible="False">
<Path Data="M0,0L56.622002,0 56.622002,14.471 35.715,14.471 35.715,64 20.715,64 20.715,14.471 0,14.471z" Stretch="Uniform" Fill="{DynamicResource ButtonForegroundNormal}" VerticalAlignment="Center" Width="15" Height="15" Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1" ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Viewbox>
<textBlock Text="{Binding Name}/>
</Grid>
</DataTemplate>
my class TypeB contains a Name(Text) and DataType(Text) Fields
if the DataType is Alpha I return AlphaTemplate in my templateSelector and so on
I have an action(dragDrop) on the window which adds items to the second level. And I want the template selector should pick up the correct datatemplate for that dropped item based on its DataType
My main ViewModel contains ICollectionView of TypeA Objects and Each TypeA ViewModel contains ICollectionView of TypeB ViewModels.
Let me know if you need anything
I dont know what is wrong with this as this will require to debug the code, but what you wanted to achieve can be done by defining the default DataTemplate for your TypeB and switching the content depending on the binding like this:
<DataTemplate DataType="{x:Type TypeB}">
<ContentControl>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate">
<Setter.Value>
<!-- Default template here for your item -->
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding XYZ}" Value="true">
<Setter Property="ContentTemplate">
<Setter.Value>
<!-- Different template for your item -->
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
Thanks

WPF databinding very slow

I had a question some time ago (this is NO duplicate) as you can see here: WPF Simple DataMatrix.
I asked about creating a matrix of LED lights on screen. I used to that the marked answer and created the matrix. It is displayed very well and I also applied commands on the Ellipse so I can edit the Matrix but also that works without any lag.
As result this is my code for the Matrix:
<ItemsControl x:Class="HTLED.WPF.Controls.LedGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:Data="clr-namespace:HTLED.Data;assembly=HTLED.Data"
xmlns:Controls="clr-namespace:HTLED.WPF.Controls"
xmlns:Commands="clr-namespace:HTLED.Client.Commands;assembly=HTLED.Client"
xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ViewModel="clr-namespace:HTLED.Client.ViewModel;assembly=HTLED.Client"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance ViewModel:LedContainerViewModel}" Name="ledGridRoot" >
<ItemsControl.Resources>
<DataTemplate x:Key="ledTemplate" DataType="{x:Type Data:Led}">
<Ellipse Name="ellipse" Fill="Green" Stretch="Uniform" SnapsToDevicePixels="True">
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="PreviewMouseMove">
<Commands:CommandTrigger Command="{Binding ElementName=ledGridRoot, Path=DataContext.LedGridViewModel.LedMouseMoveCommand}" PassEventArgsToCommand="True"/>
</Interactivity:EventTrigger>
<Interactivity:EventTrigger EventName="PreviewMouseLeftButtonDown">
<Commands:CommandTrigger Command="{Binding ElementName=ledGridRoot, Path=DataContext.LedGridViewModel.LedOnCommand}" PassEventArgsToCommand="True"/>
</Interactivity:EventTrigger>
<Interactivity:EventTrigger EventName="PreviewMouseRightButtonDown">
<Commands:CommandTrigger Command="{Binding ElementName=ledGridRoot, Path=DataContext.LedGridViewModel.LedOffCommand}" PassEventArgsToCommand="True"/>
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</Ellipse>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=State}" Value="Off">
<Setter TargetName="ellipse" Property="Fill" Value="Red"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{StaticResource ledTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Controls:StretchStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In the background I have a class called LedMatrix. It has a property with the collection of the leds:
ObservableCollection<ObservableCollection<Led>> _leds;
public ObservableCollection<ObservableCollection<Led>> Leds
{
get { return _leds ?? (_leds = CreateMatrix(XSize, YSize)); }
set { SetProperty(value, ref _leds, () => Leds); }
}
The matrix is contained by another control:
<Canvas x:Class="HTLED.WPF.Controls.LedContainer"
....
mc:Ignorable="d"
d:DataContext="{d:DesignInstance ViewModel:LedContainerViewModel}"
d:DesignHeight="300" d:DesignWidth="300" Name="layoutRoot" Drawing:DrawingCore.EnableDrawing="True">
<Viewbox Canvas.Top="0" Canvas.Left="0" Width="{Binding ElementName=layoutRoot, Path=ActualWidth}"
Height="{Binding ElementName=layoutRoot, Path=ActualHeight}">
<Grid>
<Controls:LedGrid Width="50000" Height="25000" Margin="500" DataContext="{Binding Path=Main.LedContainerViewModel}" ItemsSource="{Binding Path=LedContentContainer.Content}" />
</Grid>
</Viewbox>
As you can see I set the ItemsSource of the Matrix in the container. That Itemssource Is a Interface like this:
public interface ILedContentContainer
{
LedMatrix Content { get; set; }
}
And the LedMatrix I already showed before (the ObservableCollection<ObservableCollection<Led>>).
And now the very important:
I have the change the LedMatrix (the Itemssource of LedGrid - see LedGridContainer) very often because it is some kind of an animation. The problem is that that all is very very slow. So I wanted to ask if you know some optimations?
Again I have to change the LedMatrix very very fast.
If you apply a whole new ObservableCollection each time as Led changes, the complete grid has to be rendered again and again. You should change the State property of the Led's that are changing (they should fire PropertyChanged).
Also, if the amount of Led's is constant, you don't need an ObservableCollection at all. You can use any IEnumerable.

Building a list of options with MVVM

I have a ObservableCollection> property that I would like to display in a list box in a WPF window using the MVVM model. Ideally I would like to have a listbox that has a check box for the bool and a label for the string and when the user changes the value of the checkbox it would change the corresponding bool. What is the best way to go about doing this?
Try using an ItemsControl, and don't bind to a list of checkboxes, define a model:
<ItemsControl ItemsSource="{Binding YourModelList}">
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=Selected}"/>
<TextBlock Text="{Binding Path=Description}" />
</StackPanel>
</ItemsPanelTemplate>
</ItemsControl>
In the ViewModel:
public ObservbleCollection<YourModel> YourModelList { get; set; }
And the Model:
public class YourModel
{
public bool Selected {get;set;}
public string Description {get;set;}
public int ID {get;set;}
}
Implement INotifyPropertyChanged as necessary
Idealy, if you want to follow the MVVM approach, everyone of your elements in the ObservableCollection should be a ViewModel.
These viewModels should expose 2 properties, such as string Description and bool IsSelected.
All you need then is to provider your ListBox with a Style in order to display a checkbox and textblock for each databound ViewModel.
The following XAML implements such a Style. Note: The usercontrol DataContext should hold a ViewModel containing an ObservableCollection<YourClass> Items { get; set; } property where YourClass exposes string Description { get; set; } and bool IsSelected { get; set; }. You will obviously want to throw in some INotifyPropertyChanged magic in there.
<Grid>
<Grid.Resources>
<Style x:Key="CheckBoxListStyle" TargetType="ListBox">
<Style.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<StackPanel Orientation="Horizontal">
<CheckBox x:Name="itemChoix" Margin="5,5,0,0" IsChecked="{Binding IsSelected, Mode=TwoWay}" IsEnabled="{Binding IsEnabled, Mode=TwoWay}" />
<TextBlock Margin="5,5,0,0" Text="{Binding Description, Mode=TwoWay}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="0" />
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="1" Style="{StaticResource BoxBorder}" Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid>
<ListBox ItemsSource="{Binding Path=Items}" SelectionMode="Multiple" Style="{StaticResource CheckBoxListStyle}"/>
</Grid>
</Border>
</Grid>
Create your public ObservableCollection property in your ViewModel
Create an IsSelected bool property.
Populate collection from constructor or command.
Create a command for the checkbox that sets the IsSelected property.
Do the Xaml binding

Categories

Resources