WPF dependency property precedence & reference type Default Values

前端 未结 2 1751
暗喜
暗喜 2020-12-12 05:16

If I create a custom control like this:

public class MyControl : ContentControl
{
   public static readonly DependencyProperty ItemsProperty =                       


        
相关标签:
2条回答
  • 2020-12-12 05:50

    Can't you just specify the default property of the dependency property:

      public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
            "Items",
            typeof(ObservableCollection<object>),
            typeof(CaseDetailControl),
            new PropertyMetadata(new ObservableCollection<object>()));
    

    or am I missing what you are after?

    Edit:

    ah... in that case how about checking for null on the getter?:

        public ObservableCollection<object> Items
        {
            get
            {
                if ((ObservableCollection<object>)GetValue(ItemsProperty) == null)
                {
                    this.SetValue(ItemsProperty, new ObservableCollection<object>());
                }
    
                return (ObservableCollection<object>)GetValue(ItemsProperty);
            }
    
            set
            {
                this.SetValue(ItemsProperty, value);
            }
        }
    
    0 讨论(0)
  • 2020-12-12 05:51

    When ObservableCollection properties misbehave, I try throwing out assignments to that property. I find that the references don't translate right and bindings get lost, somehow. As a result, I avoid actually setting ObservableCollection properties (preferring, instead, to clear the existing property and add elements to it). This becomes really sloppy with a DependencyProperty because you're going to call your getter multiple times in your setter. You might want to consider using INotifyPropertyChanged instead. Anyway, here's what it'd look like:

    EDIT: Blatantly stole the getter from SteveL's answer. I reworked it a touch so that you only have a single call to GetValue, is all. Good work around.

    public ObservableCollection<object> Items
    { 
        get
        {
            ObservableCollection<object> coll = (ObservableCollection<object>)GetValue(ItemsProperty);
            if (coll == null)
            {
                coll = new ObservableCollection<object>();
                this.SetValue(ItemsProperty, coll);
            }
    
            return coll;
        }
        set 
        {
            ObservableCollection<object> coll = Items;
            coll.Clear();
            foreach(var item in value)
                coll.Add(item);
        }
    } 
    

    Note that this is depending on your default to set correctly. That means changing the static ItemsProperty default to be a new ObservableCollection of the correct type (i.e. new PropertyMetadata(new ObservableCollection()). You'll also have to remove that setter in the constructor. And note, I've no idea if that'll actually work. If not, you'll want to move to using INotifyPropertyChanged for sure...

    0 讨论(0)
提交回复
热议问题