MVVM中似乎没有刷新数据绑定 [英] Databindings don't seem to refresh in MVVM

查看:77
本文介绍了MVVM中似乎没有刷新数据绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将我的CheckBoxList从Code Behind重写为WPF C#中的MVVM模式。问题是,现在我有一个问题是获得所有选中的复选框。我已经实现了INotifyPropertyChanged接口。项目正在构建正确,当我设置断点时,我可以注意到我的复选框总是收到假值,即使它们已被选中。我想我可能在数据绑定方面做错了。拜托,有人可以提供帮助吗?我是MVVM中的新人。



我尝试过:



I am trying to rewrite my CheckBoxList from Code Behind to MVVM pattern in WPF C#. The thing is that now I have a problem to get all selected checkboxes. I have implemented INotifyPropertyChanged interface. Project is building correctly, when I set the break point I can notice that I received always false value for my checkboxes, even if they are selected. I assume that maybe I did something wrong with data binding. Please, does anybody can help? I am totally newbie in MVVM.

What I have tried:

 public class ObservableObject : INotifyPropertyChanged
    {

        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string strPropertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(strPropertyName));
        }

        #endregion

    }
}







public class SharedModel : ObservableObject
   {
               private bool _fIsSelected;

               public bool IsSelected
               {
                   get => _fIsSelected;
                   set
                   {
                       _fIsSelected = value;
                       OnPropertyChanged("IsSelected");
                   }
               }

       public bool IsSelected { get; set; }

       public string Name { get; set; }

       public string Method { get; set; }
   }










class TestViewModel : ObservableObject
    {

        public ObservableCollection<SharedModel> List { get; set; } = new ObservableCollection<SharedModel>
        {
            new SharedModel
            {
                Name = "A1",
                Method = Test(),
            },
            new SharedModel
            {
                Name = "A2",
                Method = TestOne()
            }
};

        public string GetSelectedCheckboxes()
        {
             var command =
                    from item in List
                    where item.IsSelected
                    select item.Method;
          return string.Join("\r&", new NewList<string>(command));
        }







<StackPanel Margin="0,0,769,510">
            <ListBox Name="ListBox"
                     ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                     ItemsSource="{Binding List}"
                     SelectionMode="Multiple" Background="{x:Null}" Margin="0,133,590,470" Foreground="White" BorderBrush="{x:Null}">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal"
                                    MinWidth="170" MaxWidth="170"
                                    Margin="0,0, 0, 0" >
                            <CheckBox x:Name="TestCheckbox"
                                      Tag="{Binding Method}" IsChecked="{Binding IsSelected}" />
                            <ContentPresenter
                                Content="{Binding Name}"
                                Margin="5,0, 15, 0" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </StackPanel>

推荐答案

首先,您没有在模型中实现OnChanged事件,只有视图模型。

接下来,在数据绑定中你必须要注意的一件事是new关键字。



我找到的做法为我工作最好的是声明变量



First, you don't implement OnChanged event in your model, only the view model.
Next, one thing you have to be careful with in databinding is the "new" keyword.

The practice that I have found to work the best for me is declare the variable

privateObservableCollection<SharedModel> _List;
public ObservableCollection<SharedModel> List 
{ 
    get { return _List; } 
    set { _List = value; OnPropertyChanged("List");} 
}





然后我在构造函数中初始化它,以便它只使用新关键字一次。原因是new关键字通常会破坏绑定。我不确定您是否要从viewmodel修改列表,因此我通常为模式指定Two-Way,以便我可以从view和viewmodel更改项目。我也更改了更新源触发器,但IIRC lostfocus是默认值。





Then I initialize it in the constructor so that it is only using the "new" keyword one time. The reason for this is that the "new" keyword will often "break" the binding. I am not sure if you want to modify the list from the viewmodel, so I usually specify Two-Way for the mode so that I can change items from both the view and viewmodel. I also change the update source trigger, but IIRC lostfocus is the default.

<Listview Itemssource="{Binding List, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 



然后在您的项目模板中,您的IsSelected应该更新。


Then in your item template, your IsSelected should update.

<ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal"

                                    MinWidth="170" MaxWidth="170"

                                    Margin="0,0, 0, 0" >
                            <CheckBox x:Name="TestCheckbox"

                                      Tag="{Binding Method}" IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                            <ContentPresenter

                                Content="{Binding Name}"

                                Margin="5,0, 15, 0" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>







我不知道你是否使用您可以使用命令,事件或任何其他方式来获取GetSelectedCheckboxes(),但有一百万种不同的方法可以返回所有真正的选择。一种方式可能是:










I don't know if you use a command, or event or whatever you do to get to GetSelectedCheckboxes(), but there are a million different ways to return all of the true selections. one way might be:



public string GetSelectedCheckboxes()
        {
             List<string> yourlist = List.where(l => l.IsSelected == true).Select(x => x.Method).ToList();
             return yourlist;   
        }





希望这会有所帮助,如果您需要我进一步澄清,我会告诉我。





编辑:向您展示我如何设置它。





Hope this helps, if you need me to clarify further I will just let me know.


To show you how I set it up.

public class SharedModel
   {
       public bool IsSelected { get; set; }

       public string Name { get; set; }

       public string Method { get; set; }
   }







public class TestViewModel : ObservableObject
{
    privateObservableCollection<SharedModel> _List;
    public ObservableCollection<SharedModel> List 
    { 
        get { return _List; } 
        set { _List = value; OnPropertyChanged("List");} 
    }

    public TestViewModel()
    {
        List = new ObservableCollection<SharedModel>()
        {
            new SharedModel()
            {
                Name = "A1",
                IsSelected = false
            },
            new SharedModel()
            {
                Name = "A2",
                IsSelected = false
            }
        };
    }

    public List<string> GetSelectedCheckboxes()
    {
        List<string> selectedCheckboxes = List.Where(x => x.IsSelected == true).Select(x => x.Name).ToList();
        return selectedCheckboxes;
}





这与您一起设置DataContext应该有效。您所要做的就是连接一个按钮来调用GetSelectedCheckboxes(),该列表将只是被选中的复选框。



This along with you setting the DataContext should work. All you have to do is wire up a button to call GetSelectedCheckboxes() and that list will be only checkboxes that are selected.


这篇关于MVVM中似乎没有刷新数据绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆