简体   繁体   English

如何将WPF / MVVM应用程序中ListView + GridView中的单个复选框状态绑定到集合的属性

[英]How to bind single checkbox state from ListView+GridView in WPF/MVVM app to property of collection

I've read many topics that are really close to my question but none of them clarified me how to handle my problem. 我已经阅读了许多非常接近我的问题的主题,但是没有一个主题澄清了我如何处理我的问题。

In my WPF/MVVM app I have ListView in which there is GridView. 在我的WPF / MVVM应用程序中,我具有ListView,其中有GridView。 I would like to have the first column as checkboxes. 我想将第一列作为复选框。 The ItemsSource of ListView is bind to MyItemsCollectionProperty (which is basically IEnumerable of MyClass instances). ListView的ItemsSource绑定到MyItemsCollectionProperty(基本上是MyClass实例的IEnumerable)。 My ViewModel class has that property of course. 我的ViewModel类当然具有该属性。 I was able to bind all other columns from grid to properties of MyItemsCollectionProperty properties (I mean One, Two, Three) but not the checkbox column. 我能够将网格中的所有其他列绑定到MyItemsCollectionProperty属性的属性(我的意思是“一”,“二”,“三”),而不是复选框列。 So the question is how to bind my checkbox state directly to the property of MyClass in the collection (IsMarked boolean property)? 所以问题是如何将我的复选框状态直接绑定到集合中MyClass的属性(IsMarked布尔属性)? I would appriciate any suggestions. 我会提出任何建议。

MyClass def: MyClass def:

namespace MyNamespace
{
    public class MyClass
    {
        public bool IsMarked { get; set; }
        public string One { get; set; }
        public string Two { get; set; }
        public string Three { get; set; }
    }
}

And the XAML: 和XAML:

    <ListView x:Name="listView" HorizontalAlignment="Left" Height="375" Margin="24,82,0,0" VerticalAlignment="Top" Width="750" ItemsSource="{Binding MyItemsCollectionProperty}">
        <ListView.View>
            <GridView>
                <GridViewColumn Width="30">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <CheckBox x:Name="checkBoxSelect"/>
                            </Grid>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                    <Grid>
                        <CheckBox x:Name="checkBoxSelectAll" ToolTip="Select all" IsChecked="{Binding SelectedAll}" Command="{Binding SelectAllCmd}"/>
                    </Grid>
                </GridViewColumn>
                <GridViewColumn Header="One" DisplayMemberBinding="{Binding One}"/>
                <GridViewColumn Header="Two" DisplayMemberBinding="{Binding Two}"/>
                <GridViewColumn Header="Three" DisplayMemberBinding="{Binding Three}"/>
            </GridView>
        </ListView.View>
    </ListView>

And the piece of simplified ViewModel class code (not the whole class): 还有一段简化的ViewModel类代码(不是整个类):

namespace MyNamespace.ViewModel
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private IEnumerable<MyClass> _myItemsCollectionProperty;
        public IEnumerable<MyClass> MyItemsCollectionProperty
        {
            get { return _myItemsCollectionProperty; }
            set
            {
                _myItemsCollectionProperty = value;
                OnPropertyChanged(nameof(MyItemsCollectionProperty));
            }
        }

        //(...)

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

You need to implement INotifyPropertyChanged in MyClass to enable binding. 您需要在MyClass中实现INotifyPropertyChanged才能启用绑定。

Check here how to impleement it https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-implement-property-change-notification 在此处查看如何实现它https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/data/how-to-implement-property-change-notification

For those who will experience similar problem I have the solution (based on the XAMlMAX and partially Giltanas comments). 对于那些将遇到类似问题的人,我有解决方案(基于XAMlMAX和部分Giltanas的评论)。

I am not sure if that is the best possible solution but what I've done is: 我不确定这是否是最好的解决方案,但是我所做的是:

  1. I left the MyClass almost as it was - I removed IsMarked property since it is strictly View-related - checkbox column (so I treat that class as it is strict Model class which instances are loaded by other Model class for loading them). 我几乎保持了MyClass的状态-删除了IsMarked属性,因为它严格地与视图相关-复选框列(因此,我将该类视为严格的Model类,将其实例加载到其他Model类中进行加载)。 No relation to View layer for now. 目前与View层无关。
  2. I created second class (let's call it MyClassVM) which is almost the same as MyClass. 我创建了第二类(我们称之为MyClassVM),它与MyClass几乎相同。 The difference is that this one has additional property IsMarked which is bound to checkbox column. 区别在于,此属性具有附加到复选框列的附加属性IsMarked。 Other difference is that this class implements INotifyPropertyChanged interface so it's strictly View-related. 另一个区别是该类实现了InotifyPropertyChanged接口,因此它与视图严格相关。
  3. There is async method in ViewModel for loading MyClass instance and then there is translantion from MyClass instance into MyClassVM. ViewModel中有一个用于加载MyClass实例的异步方法,然后存在从MyClass实例到MyClassVM的翻译。 MyClassVM props are bound to the View. MyClassVM道具绑定到视图。

Everything works as expected and I do believe I've got proper separation of BL (Model) and View/ViewModel. 一切都按预期进行,我相信我已经将BL(模型)和View / ViewModel进行了适当的分离。 Correct me if I'm wrong. 如果我错了纠正我。 Thanks for all the suggestions. 感谢所有的建议。 You guys helped a lot. 你们帮了很多忙。

And funny but extremally important thing. 和有趣但极端重要的事情。 What XAMlMAX suggested - after changes I've done I was given IntelliSense error in XAML but I ignored it and all the projects compiled and work as expected. XAMlMAX的建议-进行更改后,我在XAML中收到了IntelliSense错误,但我忽略了它,所有项目均按预期进行了编译和工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM