Reputation: 67
Hello Guys I am struggling with this one. I have list called "ROOT" I apply to this list's ItemTemplate "RootTemplate". Within "RootTemplate" I have another list "BRANCH" with another template "BranchTemplate", and what I am trying to achieve is to pre-select some of them listViewItems inside of BRANCH list.
<ResourceDictionary
<DataTemplate x:Key="RootTemplate" >
<ListViewItem>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="0"/>
<ColumnDefinition Width="Auto" MinWidth="0"/>
</Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding Branches}" ItemTemplate="{StaticResource BranchTemplate}" SelectionMode="Multiple"/>
</Grid>
</ListViewItem>
</DataTemplate>
<DataTemplate x:Key="BranchTemplate">
<ListViewItem IsSelected="{Binding IsChecked, Mode=TwoWay}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Width="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"/>
</Grid>
</ListViewItem>
</DataTemplate>
My ViewModel is simple
public class Root: ReactiveObject
{
public ObservableCollectionExtended<Branch> Branches{ get; } = new ObservableCollectionExtended<Branch>();}
public class Branch: ReactiveObject
{
private bool _isChecked = true;
public bool IsChecked
{
get => _isChecked;
set
{
this.RaiseAndSetIfChanged(ref _isChecked, value);
}
}
private string _name;
public string Name
{
get => _name;
set
{
this.RaiseAndSetIfChanged(ref _name, value);
}
}}
In BranchTemplate I am using binding with IsSelected to IsChecked property. It works fine, when I click on list IsChecked is changed accordingly, also when I (during-run time) change IsChecked property then I can see change reflected on UI. But I can't initialize IsChecked to true (as you can see code). Even if I do so, then when I run application IsChecked it automatically set back to false, and in UI listItems are not selected.
Upvotes: 0
Views: 215
Reputation: 3032
Referring to the document (which mentions "If you style the control template, do not try to bind properties like IsSelected or Background properties on the ListViewItemPresenter, perhaps to implement your own selection binding system, since your binding may be replaced by the control's internal mechanism."), the reason why the IsSelected
property of ListViewItem
could not be initialized may be the initialization binding is replaced with the control's internal mechanism.
As you mentioned, you could set the value of IsChecked
in code to change the IsSelected
property of a ListViewItem
and the value of IsChecked
will be changed when you click an item in ListView
, which indicates that the two-way data binding can work. Therefore, you could force certain items of ListView
named BRANCH
to be selected by adding a Loading
event to resolve the initialization binding of IsSelected
property.
For example:
……
<ListView ItemsSource="{Binding Branches}" ItemTemplate="{StaticResource BranchTemplate}" SelectionMode="Multiple" Loading="ListView_Loading"/>
……
private void ListView_Loading(FrameworkElement sender, object args)
{
var list = sender as ListView;
var root = list.DataContext as Root; //Adjust the type to your scenario
for (int i = 0; i < root.Branches.Count; i++)
{
var item = root.Branches.ElementAt(i);
if (item.IsChecked == true)
{
list.SelectedItems.Add(list.Items.ElementAt(i));
}
}
}
Upvotes: 1