Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.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# Caliburn.Micro BindableCollection未使用代码隐藏设置绑定来更新视图中的代码_C#_Wpf_Data Binding_Caliburn.micro_Inotifypropertychanged - Fatal编程技术网

C# Caliburn.Micro BindableCollection未使用代码隐藏设置绑定来更新视图中的代码

C# Caliburn.Micro BindableCollection未使用代码隐藏设置绑定来更新视图中的代码,c#,wpf,data-binding,caliburn.micro,inotifypropertychanged,C#,Wpf,Data Binding,Caliburn.micro,Inotifypropertychanged,我想使用Caliburn.Micro-MVVM创建一个WPF应用程序。其中一个视图应该可以很好地绘制为ViewModel获取的数据。在视图中,我想在代码隐藏中绘制。我使用标量依赖属性。那很好。我还可以使用BindableCollection中存储的数据(下面示例代码中的LocationList)。如果我向BindableCollection添加新元素,那么更新DependencyProperty将不起作用。这一定是个愚蠢的错误,但我看不出来。我创建了一个演示应用程序,尽可能省去了。这是一个标准的

我想使用Caliburn.Micro-MVVM创建一个WPF应用程序。其中一个视图应该可以很好地绘制为ViewModel获取的数据。在视图中,我想在代码隐藏中绘制。我使用标量依赖属性。那很好。我还可以使用BindableCollection中存储的数据(下面示例代码中的LocationList)。如果我向BindableCollection添加新元素,那么更新DependencyProperty将不起作用。这一定是个愚蠢的错误,但我看不出来。我创建了一个演示应用程序,尽可能省去了。这是一个标准的Caliburn.Micro设置。我不在这里显示引导程序、ShellView和ShellViewModel。它们是一般启动器配置

ViewModel如下所示:

    using Caliburn.Micro;
    using System.Collections.Generic;

    namespace BindingCodeBehind.ViewModels
        {
        public class DemoViewModel : Screen
            {
            private BindableCollection<string> _locationList;
            public BindableCollection<string> LocationList
                {
                get { return _locationList; }
                set
                    {
                    _locationList = value; 
                    NotifyOfPropertyChange(()=>LocationList);
                    }
                }

            public DemoViewModel()
                {
                LocationList = new BindableCollection<string>();
                }

            protected override void OnViewLoaded(object view)
                {
                base.OnViewLoaded(view);
                for (int i = 0; i < 3; i++)
                    {
                    // BindableCollection supports AddRange, but not Add. 
                    LocationList.AddRange( new List<string>{$"Test nr {i}"});
                    // LocationList.Add($"Test nr {i}");
                    }
                NotifyOfPropertyChange(()=>LocationList.Count);
                }
            }
        }
using Caliburn.Micro;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;

namespace BindingCodeBehind.Views
    {
    public partial class DemoView : UserControl
        {
        public BindableCollection<string> LocationList
            {
            get { return (BindableCollection<string>) GetValue(LocationListProperty); }
            set { SetValue(LocationListProperty, value);}
            }

        public static readonly DependencyProperty LocationListProperty =
            DependencyProperty.Register("LocationList", 
                typeof(BindableCollection<string>), 
                typeof(DemoView),
                new FrameworkPropertyMetadata(null, 
                                            FrameworkPropertyMetadataOptions.AffectsRender,
                                            new PropertyChangedCallback(OnLocationListChanged)));

        public DemoView()
            {
            InitializeComponent();
            var myBinding = new Binding
                {
                Mode = BindingMode.TwoWay,
                Path = new PropertyPath("LocationList"),
                NotifyOnSourceUpdated = true
                };
            BindingOperations.SetBinding(this, LocationListProperty, myBinding);
            }

        protected override void OnRender(DrawingContext drawingContext)
            {
            // Data from LocationLst should be used in drawing 
            }

        private static void OnLocationListChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
            // I assume this called if LocationList changes
            }
        }
    }
在代码中,将创建依赖项属性
LocationList
。在构造函数中,我为这个属性创建了一个绑定。在调试器中,我可以看到这实际上是可行的<如果此列表发生更改,则应调用code>OnLocationListChanged。当我在ViewModel的构造函数中创建
LocationList
时,我看到这被调用,但是当我向
LocationList
添加三个元素时,句柄不再被调用。因此,我认为问题在于如何处理
INotifyChange
。为了更好地理解,我查阅了
BindableCollection
类的源代码,发现
Add
方法没有实现,所以我在ViewModel中更改了我的代码以使用
AddRange
方法,只是为了确保这一点,但它没有帮助

我尝试了很多东西,但我完全不知道如何让它工作。我真的希望有人能帮我。基本上,所有这些都会导致我的应用程序再次调用OnRender来更新图形。这是我的第一个WPF绘图应用程序和我的第一个Caliburn.Micro应用程序,所以这一切对我来说仍然是新的

我的开发环境:Visual Studio 2019,社区版,.Net Core 3.1 C#8.0,Windows10。所有更新均使用最新补丁。

您认为“如果此列表更改,则应调用OnLocationListChanged”的假设是错误的

依赖项属性的回调仅在属性本身设置为新值时调用,即将其分配给
BindableCollection
的新实例时


在向集合中添加项或从集合中删除项时,不会调用它。有一个
CollectionChanged
事件,您可以处理该事件以响应添加或删除的单个项目。

非常感谢您的帮助。它还不能解决我的问题,因为我还不知道如何在视图中实现CollectionChanged事件。BindableCollection调用此事件,因此这方面没有问题。适用于PropertyChanged DependencyProperty.Register帮助,但不适用于CollectionChanged。我可以注册到事件,这是有效的,但它似乎没有被调用。我将在生成的XAML代码中看到Microsoft是如何做到这一点的。我找到了窗口的示例代码,但没有找到UserControl的示例代码。任何想法或示例代码都是免费的welcome@RudolfJan:您可以将事件处理程序连接到
OnLocationListChanged
回调中的事件。