【问题标题】:Custom Control does not save changes to property自定义控件不保存对属性的更改
【发布时间】:2018-07-09 12:28:42
【问题描述】:

我正在使用这个 DependencyProperty 来存储字符串集合:

public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( nameof( ItemsSource ) , typeof( IEnumerable<string> ) , typeof( MyClass) , new FrameworkPropertyMetadata( new List<string>() , FrameworkPropertyMetadataOptions.BindsTwoWayByDefault ) );

在 ItemsSource 的属性中,我试图过滤掉已经选择的字符串。像这样

SetValue( ItemsSourceProperty , source.Except( target ).ToList() );
return (IEnumerable<string>) GetValue( ItemsSourceProperty );

source 包含所有可能的值,定位选择的值。 source.Except(target).ToList() 工作正常,但结果永远不会存储在 DependencyProperty 中。

我做错了什么?

【问题讨论】:

  • 如果您正在绑定 ItemsSource 属性(以及其他几个所谓的值源),WPF 会绕过属性设置器并直接调用 SetValue。这就是为什么你不能在属性设置器中调用除SetValue(ItemsSourceProperty, value) 之外的任何东西。这里解释一下:XAML Loading and Dependency Properties
  • 除此之外,您不能使用new List&lt;string&gt;() 作为默认值。 MyClass 的所有实例都将在同一个集合对象上运行。
  • 这一行的最佳位置在哪里:source.Except(target).ToList()?
  • ItemsSourceProperty 的可用默认值是什么?
  • 如果有Binding,设置它的Converter。默认值应为 null。

标签: wpf custom-controls dependency-properties


【解决方案1】:

是的,我正在使用绑定。这是自定义控件的属性:

public IEnumerable<string> ItemsSource
{
    get
    {
        var source = (IEnumerable<string>) GetValue( ListBoxSourceProperty);
        var target = (IEnumerable<string>) GetValue( SelectedItemsProperty);


        if ( source == null )
        {
            source = (IEnumerable<string>) GetValue( ItemsSourceProperty );
            ListBoxSource = source;
        }


        if ( source.ToList().Count == 0 )
        {
            source = (IEnumerable<string>) GetValue( ItemsSourceProperty );
            ListBoxSource = source;
        }

        var tmp = source.Except( target ).ToList(); // tmp.Count() = 5

        SetValue( ItemsSourceProperty , tmp ); // nothing is written here

        var tmp2 =(IEnumerable<string>) GetValue( ItemsSourceProperty );  // tmp2.Count() = 6 !!!


        OnPropertyChanged( "ItemsSource" );
        return tmp;  // the control displays 6 elements every time
    }

    set
    {
        SetValue( ItemsSourceProperty , value );
    }
}

这是 DataContext 中的属性

public ObservableCollection<string> ItemSource
{
    get
    {
        if ( _itemsSource == null )
        {
            _itemsSource = new ObservableCollection<string>( _catalog );
        }

        return _itemsSource;
    }
    set { /*_itemsSource = value;*/ }
}

_catalog 和 _itemSource 是 List 类型

最后是 xaml 文件中的绑定表达式:

<local:MyControl ItemsSource="{Binding ItemSource}" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多