UWP listview绑定

时间:2016-10-12 14:42:33

标签: xaml listview uwp

将listview项的选定状态绑定到模型的布尔属性的最简单方法是什么?

我有模特:

class Model {
    public string Name { get; set; }
    public bool Selected { get; set; }
}

和listview:

<ListView x:Name="myListView" SelectionMode="Multiple">
<ListView.ItemTemplate>
    <DataTemplate x:DataType="x:String">
        <TextBlock Text="{Binding Name}"/>
    </DataTemplate>
</ListView.ItemTemplate>

我将项目绑定到列表视图:

myListView.ItemsSource = // list of Model instances

我希望Model的Selected属性始终反映是否在myListView中选中它。因此 - 通过选择/取消选择myListView中的项目,它将保留适当的bool值或通过设置Selected属性myListView将选择/取消选择适当的项目。

2 个答案:

答案 0 :(得分:2)

  

将列表视图项的选定状态绑定到模型的布尔属性的最简单方法是什么?

我不确定这是否是最简单的方式,但对我来说,我认为这是将ListViewItem Selected绑定到ListView属性的最简单方法模型。只有问题是,我们都知道ListViewItem的每个项目都是DataTemplate的实例,但是当我们使用ListViewItem来构建ListViewItem的项目结构时,{{1在设计时不可用。所以我的想法是将这个属性绑定在代码后面,例如:

<ListView x:Name="myListView" SelectionMode="Multiple" Loaded="myListView_Loaded" ItemsSource="{x:Bind Collection}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
代码背后的代码:

private ObservableCollection<Model> Collection = new ObservableCollection<Model>();

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    for (int i = 0; i < 100; i++)
    {
        Collection.Add(new Model { Name = "Name " + i });
    }
}

private void myListView_Loaded(object sender, RoutedEventArgs e)
{
    IEnumerable<ListViewItem> lvItems = FindVisualChildren<ListViewItem>(myListView);
    if (lvItems != null)
    {
        foreach (ListViewItem lvitem in lvItems)
        {
            Model model = lvitem.Content as Model;
            Binding b = new Binding
            {
                Source = model,
                Path = new PropertyPath("Selected"),
                Mode = BindingMode.TwoWay,
            };
            BindingOperations.SetBinding(lvitem, ListViewItem.IsSelectedProperty, b);
        }
    }
}

private static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
    if (depObj != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
            if (child != null && child is T)
            {
                yield return (T)child;
            }

            foreach (T childOfChild in FindVisualChildren<T>(child))
            {
                yield return childOfChild;
            }
        }
    }
}

public class Model : INotifyPropertyChanged
{
    public string Name { get; set; }

    private bool _Selected;

    public bool Selected
    {
        get { return _Selected; }
        set
        {
            if (value != _Selected)
            {
                _Selected = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName]string propertyName = "")
    {
        if (this.PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

答案 1 :(得分:0)

我认为完美的方法是实现ListView.ItemSelectionChanged事件,并遍历列表视图模型中的每个项目,将其设置为对于所选项目为true,对其余项目为false。

然而,你可能想尝试这样的事情,虽然老实说我不确定这是不是正确的方法:

class Model {
    public string Name { get; set; }
    public bool Selected 
    {
        get
        {
            return MyListView.SelectedItems.Count(x => x.Name == Name) > 0;
        }
    }
}