Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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# 带有自定义项的UserControl资源不';无法检测到变化_C#_Wpf_Xaml_User Controls - Fatal编程技术网

C# 带有自定义项的UserControl资源不';无法检测到变化

C# 带有自定义项的UserControl资源不';无法检测到变化,c#,wpf,xaml,user-controls,C#,Wpf,Xaml,User Controls,我有一个简单的UserControlwhere-is-defined属性ItemsSource public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(Dictionary<string, object>), typeof(UserControl1), new FrameworkPropertyM

我有一个简单的
UserControl
where-is-defined属性
ItemsSource

public static readonly DependencyProperty ItemsSourceProperty =
         DependencyProperty.Register("ItemsSource", typeof(Dictionary<string, object>), typeof(UserControl1), new FrameworkPropertyMetadata(null,
    new PropertyChangedCallback(UserControl1.OnItemsSourceChanged)));

public Dictionary<string, object> ItemsSource
    {
        get { return (Dictionary<string, object>)GetValue(ItemsSourceProperty); }
        set
        {
            SetValue(ItemsSourceProperty, value);
        }
    }

private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UserControl1 control = (UserControl1)d;
            control.DisplayInControl();
        }

更新:我向解决方案迈出了一小步。我有下一种风格:

<Style.Triggers>
            <DataTrigger Binding="{Binding ItemsSource, RelativeSource={RelativeSource Self}}" Value="{x:Null}">
                <Setter Property="IsEnabled" Value="False" />
            </DataTrigger>
            <DataTrigger Binding="{Binding ItemsSource.Count, RelativeSource={RelativeSource Self}}" Value="0">
                <Setter Property="IsEnabled" Value="False" />
            </DataTrigger>
        </Style.Triggers>


我将其应用于我的控件(如果没有itemSource,则禁用控件)。当我在单击时更新控件源时,我看到控件已启用,所以ItemsSource不是空的(从一开始就是空的)。所以,如果我正确理解了这种行为,现在的问题只是重新绘制控件内容。

如果您有一个字典作为数据类型,并且您在字典中添加或删除了一个值,那么您的属性实际上并没有改变。仅当您实际将此属性设置为引用其他字典时,才会触发此事件

如果需要wpf自动检测字典中是否添加或删除了项,则应使用ObservableCollection

  • 将Dictionary替换为ObservableCollection,Dictionary在添加、更新、删除项时不会触发propertyChanged事件
  • 编写自己的字典以手动触发propertychanged事件

  • 我发现问题在于,您正在为自定义
    UserControl
    中的
    ComboBox
    控件构建一个新的
    ItemsSource
    ,并且您希望
    MultiSelectCombo.ItemsSource
    UserControl1.ItemsSource
    保持同步。当简单地绑定一个
    字典
    时,这种情况是不会发生的,即使绑定一个
    可观察集合
    ,这种情况也不会发生,除非您显式地处理它

    要完成您所追求的目标,首先您需要自定义控件的
    ItemsSource
    类型能够通知我们集合更改,例如(我将在本例中使用它,正如您在上面的链接中所做的那样)。然后,您需要在您的控制范围内更新
    组合框
    项源
    ,以保持它们的同步

    private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = (MultiSelectComboBox)d;
    
        // Since we have to listen for changes to keep items synced, first check if there is an active listener to clean up.
        if (e.OldValue != null)
        {
            ((ObservableCollection<Node>)e.OldValue).CollectionChanged -= OnItemsSource_CollectionChanged;
        }
    
        // Now initialize with our new source.
        if (e.NewValue != null)
        {
            ((ObservableCollection<Node>)e.NewValue).CollectionChanged += OnItemsSource_CollectionChanged;
            control.DisplayInControl();
        }
    }
    
    private void OnItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        DisplayInControl();
    }
    

    只需让包装好的
    组合框
    使用提供给自定义控件的
    项资源

    在类的静态构造函数中定义DP。public static readonly dependencProperty ItemsSourceProperty;静态YourClassName(){ItemsSourceProperty=DependencyProperty.Register(“ItemsSource”,typeof(Dictionary),typeof(UserControl1),new FrameworkPropertyMetadata(null,new PropertyChangedCallback(UserControl1.OnItemsSourceChanged));}@AnjumSKhan-我试过之后,我收到异常-
    附加信息:“ItemsSource”属性已由“UserControl1”注册。
    将代码上载到您使用的位置。@AnjumSKhan,请检查更新。希望这对您没问题我已经尝试了
    observateCollection
    ,但我的控件的
    ItemsSource
    还是一样的。为了澄清,您是否在添加或删除项目时尝试更新控件?另外,是否可以在问题的底部发布用户控件的xaml?也许这会澄清你需要做什么来解决这个问题。我的控件来自此帖子我尝试了ObservableCollection,但仍然是ItemsSource我的控件是相同的
    ((ObservableCollection)e.OldValue)
    应该是
    e.NewValue
    ?我尝试了“更简单”的示例,但这并不能解决我的问题。不知道为什么…@demo是的,对不起,这是复制粘贴的错误。你是对的,应该是
    e.NewValue
    。这两种解决方案都能解决您的问题吗?似乎您应该能够将
    UserControl
    ItemsSource
    传递到
    ComboBox
    ,并且仍然可以使用它。您确定项目已添加到正确的源实例?谢谢,Mike。你的回答帮助我:)。问题是,我如何修改我的
    可观察集合
    。首先,我在循环中添加了
    Types.Add(element)
    等元素。但现在我尝试了next
    Types=newobservetecollection(list)
    其中list是我逐个添加的元素的容器。所以现在它起作用了。这样做可以吗?@demo初始化控件很好,只要您了解在
    Types=new observetecollection(list)
    调用之后向
    list
    添加元素不会将它们包括在呈现的控件中。
    private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = (MultiSelectComboBox)d;
    
        // Since we have to listen for changes to keep items synced, first check if there is an active listener to clean up.
        if (e.OldValue != null)
        {
            ((ObservableCollection<Node>)e.OldValue).CollectionChanged -= OnItemsSource_CollectionChanged;
        }
    
        // Now initialize with our new source.
        if (e.NewValue != null)
        {
            ((ObservableCollection<Node>)e.NewValue).CollectionChanged += OnItemsSource_CollectionChanged;
            control.DisplayInControl();
        }
    }
    
    private void OnItemsSource_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        DisplayInControl();
    }
    
    private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var control = (MultiSelectComboBox)d;
        control.MultiSelectCombo.ItemsSource = (IEnumerable)e.NewValue;
    }