【问题标题】:custom DependecyProperty not working as intended自定义 DependecyProperty 未按预期工作
【发布时间】:2017-11-03 14:37:12
【问题描述】:

我创建了一个自定义用户控件。它基本上是一个允许多选的组合框(每个组合框项都是一个复选框)。除了 Selected items 属性外,一切正常

public static readonly DependencyProperty SelectedItemsProperty =
     DependencyProperty.Register("SelectedItems", typeof(ObservableCollection<string>), typeof(MultiSelectionComboBox), new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(MultiSelectionComboBox.OnSelectedItemsChanged)));


public ObservableCollection<string> SelectedItems
{
    get { return (ObservableCollection<string>)GetValue(SelectedItemsProperty); }
    set
        {
            SetValue(SelectedItemsProperty, value);
        }
}


private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    MultiSelectionComboBox control = (MultiSelectionComboBox)d;
    control.SetText();
}

在这方面,事情似乎有效,这意味着 SelectedItems 发生变化,并且当我选择新项目时触发回调。当我使用这个自定义用户控件时,问题就出现了。

我是这样定义的:

<views:MultiSelectionComboBox SelectedItems="{Binding Path=IpAddressSelection, UpdateSourceTrigger=PropertyChanged}" Background="White" BorderThickness="1" ItemsSource="{Binding Path=Address}" BorderBrush="LightGray" Grid.Row="0" Grid.Column="1" Width="200" Margin="70 10 0 0" DefaultText="Indirizzo IP..." />

这是 SelectedItems 属性的绑定:

public ObservableCollection<string> IpAddressSelection
{
    get { return ipAddressSelection; }
    set
    {
        SetField(ref ipAddressSelection, value, "IpAddressSelection");
    }
}

private ObservableCollection<string> ipAddressSelection = new ObservableCollection<string>();

SetField 是一个实现 INotifyPropertyChanged 接口的函数。我的问题是,当我选择一个项目时,IpAddressSelection 没有看到任何变化(即我无​​法进入 IpAddressSelection 的“集合”)。你知道我在这里做错了什么吗?

【问题讨论】:

  • 为什么选择项目时会调用 IpAddressSelection 属性的设置器?仅当您将 IpAddressSelection 属性设置或绑定到 ObservableCollection... 时才会调用它
  • 刚刚阅读您的评论,我发现我的错误。我需要在绑定中设置 Mode=TwoWay。我需要 IpAddressSelection 来存储 SelectedItems
  • 所以它现在可以正常工作了?
  • 是的。我会留下答案,而不是删除问题。也许它对某人有用
  • 属性类型为ObservableCollection&lt;string&gt;有什么原因吗?您似乎没有在任何地方注册任何 CollectionChanged 甚至处理程序。除了string,您也无法使用任何其他项目类型。

标签: c# wpf dependency-properties


【解决方案1】:

就像例如Selector.SelectedItem 属性,默认情况下,您的 SelectedItems 属性应绑定双向。

注册时设置FrameworkPropertyMetadataOptions.BindsTwoWayByDefault

public static readonly DependencyProperty SelectedItemsProperty =
    DependencyProperty.Register(
        nameof(SelectedItems),
        typeof(IEnumerable),
        typeof(MultiSelectionComboBox),
        new FrameworkPropertyMetadata(
            null,
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
            OnSelectedItemsChanged));

public IEnumerable SelectedItems
{
    get { return (IEnumerable)GetValue(SelectedItemsProperty); }
    set { SetValue(SelectedItemsProperty, value); }
}

如果您需要对 SelectedItems 集合的更改做出反应,您可以检查它是否实现了 INotifyCollectionChanged 接口,并附加/分离处理程序方法。参见例如this answer.

【讨论】:

    【解决方案2】:

    发现我的错误。我需要在绑定中设置双向模式

    <views:MultiSelectionComboBox SelectedItems="{Binding Path=IpAddressSelection, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Background="White" BorderThickness="1" ItemsSource="{Binding Path=Address}" BorderBrush="LightGray" Grid.Row="0" Grid.Column="1" Width="200" Margin="70 10 0 0" DefaultText="Indirizzo IP..." />
    

    【讨论】:

    • A SelectedItems 属性当然应该默认绑定双向,例如列表框.SelectedItem。注册时设置FrameworkPropertyMetadataOptions.BindsTwoWayDyDefault
    • @Clemens 那是我不知道的。如果您在写下应如何定义属性的地方发布答案,我会将您标记为已接受
    • 请注意UpdateSourceTrigger=PropertyChanged 是默认值。您不需要显式设置它。
    猜你喜欢
    • 2022-11-11
    • 2018-03-09
    • 2017-01-01
    • 2021-10-22
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    相关资源
    最近更新 更多