簡體   English   中英

WPF自定義DependencyProperty綁定-SetValue設置正確的值,但綁定的屬性集收到null

[英]WPF Custom DependencyProperty Binding - SetValue set correct value but binded property set receive null

我的控件中的自定義DependencyProperty出現問題。 讓我解釋:

我可以控制可檢查項目的列表。 我需要將屬性綁定到IEnumerable SelectedItems。 SelectedItemsProperty填充的邏輯在控件內部,因此它不僅是簡單的綁定。 這是我的控件后面的代碼:

    public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register("SelectedItems", typeof(IEnumerable<object>), typeof(ButtonColumnFilter));

    public IEnumerable<object> SelectedItems
    {
      get { return (IEnumerable<object>)GetValue(SelectedItemsProperty); }
      set { Debug.WriteLine("SelectedItems has been set in ButtonColumnFilter - Count:{0}", value?.Count());
            SetValue(SelectedItemsProperty, value);
          }
     }

在這里,我會收到帶有正確數目的所選項目的Debug消息,因此控件內部的邏輯運行良好。 XAML中的屬性在此處綁定:

    <MESControls:ButtonColumnFilter CanSearch="True" CanSort="False" DisplayMemberPath="DisplayName"
ItemsSource="{Binding Path=FilterAdapter.Drivers, Mode=OneWay, IsAsync=True}"
OnApplyFilter="Drivers_ApplyFilter"
SelectedItems="{Binding Path=SelectedFilterDrivers, Mode=TwoWay}"/>

屬性是在我的代碼中定義的:

public IEnumerable<Driver> SelectedFilterDrivers
        {
            get => _SelectedFilterDrivers;
            set
            {

                Debug.WriteLine("SelectedFilterDrivers has been set in PlannerFilterAdapter - Count: {0}", value?.Count());
                if (_SelectedFilterDrivers != value)
                {

                    _SelectedFilterDrivers = value;
                    NotifyPropertyChanged("SelectedFilterDrivers");
                }
            }
        }

!!! 但是在這里我得到了調試信息'value == null'!!!

綁定工作良好,我想及時會正確調用屬性集。 奇怪的是,控件內部的SetValue具有正確的值,但是在代碼外部,屬性設置的值為null。

有什么事嗎 謝謝。

更新:

這是更改控件內部的SelectedItems的代碼:

private void CheckableItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {

            if (e.PropertyName == "IsChecked" && !_IsChecking)
            {
                _IsChecking = true;

                CheckableItem item = sender as CheckableItem;

                if(item.IsChecked == true && InnerItemsSource.Where(ci=>ci.Item.ToString() != SELECTALL).All(ci=>ci.IsChecked == true))
                {
                    InnerItemsSource.Single(ci => ci.Item.ToString() == SELECTALL).IsChecked = true;
                    SelectAllIsSelected = true;
                }
                else if (InnerItemsSource.Where(ci => ci.Item.ToString() != SELECTALL).All(ci=>ci.IsChecked == true) || InnerItemsSource.Where(ci => ci.Item.ToString() != SELECTALL).All(ci => ci.IsChecked == false))
                {
                    InnerItemsSource.Single(ci => ci.Item.ToString() == SELECTALL).IsChecked = false;
                    SelectAllIsSelected = false;
                } 
                else 
                {
                    InnerItemsSource.Single(ci => ci.Item.ToString() == SELECTALL).IsChecked = null;
                    SelectAllIsSelected = false;
                }

                SelectedItems = CheckedItems;

                NotifyPropertyChanged("IsFilterUsed");
                NotifyPropertyChanged("FilterIcon");


            }

            _IsChecking = false;
        }

public IEnumerable<object> CheckedItems
        {
            get
            {
                return InnerItemsSource?.Where(ci => ci.IsChecked == true && ci.Item.ToString() != SELECTALL).Select(ci => ci.Item);
            }

        }

但是正如我所寫的那樣,控件內部設置的屬性會接收正確的值,而我猜類型也正確。 CheckedItems的返回值為IEnumerable'< 對象 >'。

感謝幫助。

值為IEnumerable <Driver>

調用堆棧情況

這是集合的可見計數,僅在調用堆棧中退后一步 這是集合的可見計數,僅在調用堆棧中退后一步

調用堆棧的下一步-斷點-值為null 調用堆棧的下一步-斷點-值為null 事實是,在這些步驟之間是一些外部代碼-但我沒有收到任何錯誤,也沒有警告 事實是,在這些步驟之間是一些外部代碼-但我沒有收到任何錯誤,也沒有警告

更新-一些進展

我嘗試將公共IEnumerable < 驅動程序 > SelectedFilterDrivers更改為

public IEnumerable<object> SelectedFilterDrivers
        {
            get => _SelectedFilterDrivers;
            set
            {

                Debug.WriteLine("SelectedFilterDrivers has been set in PlannerFilterAdapter - Count: {0}", value?.Count());
                if (_SelectedFilterDrivers != value)
                {

                    _SelectedFilterDrivers = (IEnumerable<Driver>)value;
                    NotifyPropertyChanged("SelectedFilterDrivers");
                }
            }
        }

而且我收到的物品數量正確。 因此,在重新鍵入集合中的項目期間存在一個問題。 因此,我需要提出一種更好的方法,即如何保持SelectedItems使用通用IEnumerable < object >的能力。

重要的是,IEnumerable < object >可以與簡單綁定很好地工作(在這種情況下,ItemsSource-確實是,它只是OneWay綁定)

在不深入研究代碼的情況下,您是否嘗試過使用SetCurrentValue而不是SetValue

看到這個答案

IEnumerable<object>IEnumerable<Driver>沒有隱式轉換。 您應該在控件中將SelectedItems設置為IEnumerable。

順便說一句,如果最終您不想將您選擇的驅動程序列表實現為可觀察的集合,並且希望偵聽控件中的更改,那么在控件方面,您可以嘗試轉換為INotifyCollectionChanged,它將為您提供事件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM