Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVVM中的双向数据绑定问题_C#_Winforms_Design Patterns_Mvvm - Fatal编程技术网

C# MVVM中的双向数据绑定问题

C# MVVM中的双向数据绑定问题,c#,winforms,design-patterns,mvvm,C#,Winforms,Design Patterns,Mvvm,我正在尝试构建一个简单的C#/WinFoms项目,该项目根据结构使用模型视图模型设计模式: 两个UserControls和关联的ViewModels之间的数据绑定无法正常工作 main表单包含两个用户控件(UC):UC\u创建,UC\u迭代。 每个UC包含一个组合框,该组合框连接到ViewModel_xxx中的关联属性,即 Uc_Create具有: this.comboBox1ComplexCreate.DataSource = oVM_Create.VM_Create_ListOfStrin

我正在尝试构建一个简单的C#/WinFoms项目,该项目根据结构使用模型视图模型设计模式:

两个UserControls和关联的ViewModels之间的数据绑定无法正常工作

main表单
包含两个用户控件(UC):
UC\u创建
UC\u迭代
。 每个UC包含一个组合框,该组合框连接到ViewModel_xxx中的关联属性,即

Uc_Create具有:

this.comboBox1ComplexCreate.DataSource = oVM_Create.VM_Create_ListOfStringsInModel; 
this.comboBox1ComplexIteration.DataSource = oVM_Iteration.VM_Iteration_ListOfStringsInModel;
Uc_迭代具有:

this.comboBox1ComplexCreate.DataSource = oVM_Create.VM_Create_ListOfStringsInModel; 
this.comboBox1ComplexIteration.DataSource = oVM_Iteration.VM_Iteration_ListOfStringsInModel;
问题:

namespace Small_MVVM
{

    public class Model 
    {
        private static readonly object m_oLock = new object();

        private static Model instance;


        public List<string> simplelistOfStrings; 

        private Model()
        {
            simplelistOfStrings = new List<string>();
        }

        public static Model GetInstance()
        {
            if (instance == null)
            {
                lock (m_oLock)
                {
                    if (instance == null)
                    {
                        instance = new Model();
                    }
                }
            }
            return instance;
        }
    }
}
当我将元素添加到
VM_Iteration_ListOfStringsInModel
中时,相应UC(
comboBox1ComplexCreate
)和中的组合框中的列表已正确更改,但
UC_Iteration
中的另一个组合框(
Combox1ComplexIteration
)不正确

为什么

如果我将模型中的
列表
更改为
绑定列表
,则一切正常。我做错了什么

提前谢谢


型号:

namespace Small_MVVM
{

    public class Model 
    {
        private static readonly object m_oLock = new object();

        private static Model instance;


        public List<string> simplelistOfStrings; 

        private Model()
        {
            simplelistOfStrings = new List<string>();
        }

        public static Model GetInstance()
        {
            if (instance == null)
            {
                lock (m_oLock)
                {
                    if (instance == null)
                    {
                        instance = new Model();
                    }
                }
            }
            return instance;
        }
    }
}

如果您遵循MVVM模式,那么您应该使用
ObservableCollection
进行如下收集

   private ObservableCollection<int> _intList;
   public ObservableCollection<int> IntList
     {
        get
        {
          return _intList;
        }
        set
        {
           _intList= value;
           _intList.CollectionChanged += 
                        new System.Collections.Specialized.NotifyCollectionChangedEventHandler
                                            (MyProperty_CollectionChanged);
            }
        } 

void MyProperty_CollectionChanged(object sender,                        
         System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
  {
     NotifyPropertyChanged("IntList");
 }
private observeCollection\u intList;
公共可观测集合IntList
{
得到
{
返回_intList;
}
设置
{
_intList=值;
_intList.CollectionChanged+=
新System.Collections.Specialized.NotifyCollectionChangedEventHandler
(MyProperty_CollectionChanged);
}
} 
void MyProperty\u CollectionChanged(对象发送方,
System.Collections.Specialized.NotifyCollectionChangedEventArgs(e)
{
NotifyPropertyChanged(“IntList”);
}
—表示一个动态数据收集,在添加、删除项目或刷新整个列表时提供通知


您还可以检查以下内容:

我认为您的问题在于两个绑定列表之间没有链接

将项添加到VM_Iteration_ListofStringsModel时,更改将传播到绑定组合框和模型中的基础列表。但是模型中的列表无法将这些更改进一步传播到VM_Create_ListofStringsModel,因为它不支持此功能。VM_Create_ListofStringsModel将包含您添加到VM_Iteration_ListofStringsModel的项,但它不会引发ListChanged事件,因为模型中的列表会断开事件链。列表无法引发ListChanged事件。这就是BindingList存在的目的

正如您已经尝试过的,当您用BindingList替换模型中的列表时,它会起作用

因此,您已经提到的一种解决方案是,如果这是您的选项,那么另一种解决方案是对两个组合框只使用一个共享绑定列表

    private void ListDemo()
    {

        var l = new List<string>();
        l.Add("A");

        BindingList<string> blist1 = new BindingList<string>(l);
        BindingList<string> blist2 =new BindingList<string>(l);
        blist1.ListChanged += Blist1_ListChanged;
        blist2.ListChanged += Blist2_ListChanged;


        blist1.Add("B");
        // at this point blist1 and blist2 items count is 2 but only blist1 raised ListChanged
    }

    private void Blist2_ListChanged(object sender, ListChangedEventArgs e)
    {
        //No event fired here when adding B
    }

    private void Blist1_ListChanged(object sender, ListChangedEventArgs e)
    {
       // event fired when adding B
    }
private void ListDemo()
{
var l=新列表();
l、 添加(“A”);
BindingList blist1=新的BindingList(l);
BindingList blist2=新的BindingList(l);
blist1.ListChanged+=blist1\u ListChanged;
blist2.ListChanged+=blist2\u ListChanged;
blist1.添加(“B”);
//此时,blist1和blist2项计数为2,但只有blist1项发生了更改
}
私有无效Blist2_ListChanged(对象发送方,ListChangedEventArgs e)
{
//添加B时,此处未激发任何事件
}
私有无效Blist1_ListChanged(对象发送方,ListChangedEventArgs e)
{
//添加B时激发的事件
}

通过初始化使用
模型的
绑定列表
的新对象来定义它们的属性(
VM\u迭代
VM\u创建
列表StringsinModel
),该对象使用
模型。simplelistOfStrings
作为指定的源列表。因此,两个视图模型都有不同的对象,即模型中的ListofStringsModel,它们并不指向同一个对象

显然,您应该将
simplelistOfStrings
属性定义为
BindingList
,以便可以在
视图
代码隐藏
中建立双向数据绑定机制。但是,与在
ViewModel\u Iteration
ViewModel\u Create
ViewModels中定义新成员变量不同,我建议您更改属性定义,如下所示:

        public BindingList<string> VM_Iteration_ListOfStringsInModel
        {
            get
            {
                return oModel.simplelistOfStrings;
            }
            set
            {
                oModel.simplelistOfStrings = value;
                this.FirePropertyChanged(nameof(VM_Iteration_ListOfStringsInModel));
            }
        }
视图模型_创建

            public BindingList<string> VM_Create_ListOfStringsInModel
            {
                get
                {

                    return oModel.simplelistOfStrings;
                }
            }
VM_Create_ListOfStringsInModel.Clear();
VM_Create_ListOfStringsInModel.Add(item); // Or use AddRange to add Range.

尝试将数据源绑定到viewmodel属性
this.comboBox1ComplexCreate.Bindings.Add(“数据源”,oVM_Create,“VM_Create_ListOfStringsInModel”,true)
Grazie Fabio!不幸的是,它仍然不起作用:(您尝试过observablecollection吗?用两个视图共享一个视图模型是错误的做法。即使我们可以概念化或想象这一点。
            public BindingList<string> VM_Create_ListOfStringsInModel
            {
                get
                {

                    return oModel.simplelistOfStrings;
                }
            }
VM_Create_ListOfStringsInModel.Clear();
VM_Create_ListOfStringsInModel.Add(item); // Or use AddRange to add Range.