![](/img/trans.png)
[英]Issue with binding custom DependencyProperty to ListView.SelectedItem
[英]Binding to TreeView SelectedItem works as ItemsSource but not for custom DependencyProperty
我有一個 TreeView,它的 ItemsSource 有一個 ICollection<...>。 現在我正在嘗試在其他一些控件中使用 SelectedItem。 出於某種原因,我可以使用 ElementName 為 ListView 正確設置綁定,但是當我嘗試為自定義 DependencyProperty 實現相同的綁定時,它永遠不會更新。
這是 XAML(ListView 有效,MyControl 無效):
<ListView ItemsSource="{Binding ElementName=myTreeView, Path=SelectedItem.Children}" />
<modules:MyControl Grid.Row="1" Blubbi="{Binding ElementName=myTreeView, Path=SelectedItem}" />
以及 MyControl 的 DependencyProperty:
public static readonly DependencyProperty BlubbiProperty = DependencyProperty.Register(
nameof(Blubbi), typeof(object), typeof(MyControl), new PropertyMetadata(default(object)));
public object Blubbi
{
get => (object) GetValue(BlubbiProperty);
set => SetValue(BlubbiProperty, value);
}
我懷疑 DependencyProperty 的實現有些問題,但我不知道是什么。
我認為您的依賴屬性在技術上沒有任何問題,但它的實現方式看起來也不是特別有用。 通常在實現依賴屬性時,您希望在它接收到新值時發生一些事情。 最基本的方法是使用值更改回調。 例如:
public static readonly DependencyProperty BlubbiProperty = DependencyProperty.Register(
nameof(Blubbi), typeof(object), typeof(MyControl),
new PropertyMetadata(default(object), (d, e) => ((MyControl)d).OnBlubbiChanged(e.oldValue, e,newValue)));
private void OnBlubbiChanged(object oldValue, object newValue)
{
// Do something here
}
你也可以做更高級的事情來響應新的傳入值,但通常不需要。 如果你想了解更多,這里有一篇文章。
現在所有這一切都適用於任何DependencyObject
,但如果您是從FrameworkElement
擴展的元素,大多數元素都這樣做,那么您可以使用FrameworkPropertyMetadata代替PropertyMetadata
,后者以FrameworkPropertyMetadataOptions的形式提供一些額外的便利功能。
因此,假設您在元素的OnRender
覆蓋中使用此屬性,那么您可以確保在屬性值更改時渲染自動失效,以便再次調用OnRender
。
public static readonly DependencyProperty BlubbiProperty = DependencyProperty.Register(
nameof(Blubbi), typeof(object), typeof(MyControl),
new FrameworkPropertyMetadata(default(object), FrameworkPropertyMetadataOptions.AffectsRender));
此外,如果您的元素是使用 XAML 定義的模板來表示自身的Control
,那么您可以保持依賴屬性不變,並通過TemplateBinding
在您的控件模板中使用它。
<ControlTemplate TargetType="{x:Type myNamespace:MyControl}">
<TextBlock Text="{TemplateBinding Blubbi}" />
</ControlTemplate>
所以當你說你的財產永遠不會更新時,我不得不問你是怎么知道的? 您提供的代碼不完整,但看起來您實際上並沒有對屬性進行任何可以明顯改變它的事情。
作為附加說明,因為這經常讓人們感到驚訝,所以您為包裝依賴項屬性而定義的屬性將永遠不會通過綁定調用。 綁定使用依賴 object 系統直接更新依賴屬性。 盡管需要包裝器屬性才能從 XAML 設置屬性,但在處理依賴屬性時實際上並未調用它。 換句話說,包裝器屬性的設置器中的斷點永遠不會命中。 所以,永遠不要在包裝屬性中放置任何重要的邏輯。
編輯:如果您仍在努力找出問題所在,您可以通過將TraceLevel
附加屬性設置為High
來獲取綁定以將調試信息打印到調試器的 output window,如下所示:
<modules:MyControl
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
Blubbi="{Binding ElementName=myTreeView, Path=SelectedItem, diag:PresentationTraceSources.TraceLevel=High}" />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.