UWP - ListViewItem IsSelected 绑定两种不取初始值的绑定方式

问题描述

@H_404_0@大家好,我正在努力解决这个问题。我有一个名为“ROOT”的列表,我应用于这个列表的 ItemTemplate“Roottemplate”。在“Roottemplate”中,我有一个列表“BRANCH”和另一个模板“BranchTemplate”,我想要实现的是在 BRANCH 列表中预先选择其中的一些 listViewItems。

<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>
@H_404_0@我的 viewmodel 很简单

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);
        }
    }}
@H_404_0@在 BranchTemplate 中,我使用 IsSelected 绑定到 IsChecked 属性。它工作正常,当我单击列表 IsChecked 会相应更改时,也当我(在运行时)更改 IsChecked 属性时,我可以看到更改反映在 UI 上。但是我无法将 IsChecked 初始化为 true(如您所见的代码)。即使我这样做,当我运行应用程序 IsChecked 时,它会自动设置回 false,并且在 UI 列表项中不会被选中。

解决方法

参考document(其中提到“如果您设置控件模板的样式,请不要尝试在 ListViewItemPresenter 上绑定 IsSelected 或 Background 属性之类的属性,也许是为了实现您自己的选择绑定系统,因为您的绑定可能替换为控件的内部机制。”),IsSelectedListViewItem 属性无法初始化的原因可能是初始化绑定替换为控件的内部机制。

正如您所提到的,您可以在代码中设置 IsChecked 的值来更改 IsSelectedListViewItem 属性,并且 IsChecked 的值将在您更改点击ListView中的一项,表示双向数据绑定可以工作。因此,您可以通过添加 ListView 事件来解决 BRANCH 属性的初始化绑定,从而强制选择名为 LoadingIsSelected 的某些项目。

例如:

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