2016-04-26 44 views
0

我有UserControl,其中,所述關鍵視覺元素被呈現這樣的:綁定到用戶控件的DataContext:更新ContentTemplateSelector當某些屬性改變

<ContentPresenter Content="{Binding}" 
    ContentTemplateSelector="{StaticResource MStatusDisplaySelector}" /> 

的該元素的DataContext(即結合靶)是UserControl本身。 MStatusDisplaySelector是一個複雜的選擇器,它根據UserControl(它們都是簡單的DependencyProperty)的幾個屬性來選擇DataTemplate

問題是,當這些屬性中的任何一個改變時,可能需要選擇不同的模板,並且我想更新ContentPresenter。這顯然不會發生。解決此問題的最佳方法是什麼?

理想情況下,我想避免在每個涉及的屬性中實現更改回調。不僅這太冗長,而且模板選擇器稍後可能需要使用一組不同的屬性,並且保持同步並不方便。但是,更新任何屬性更改的模板也可能是正常的。

P.S.假設MStatusDisplaySelector邏輯太複雜,無法簡化爲使用Style.Triggers的傳統樣式選擇器。我希望它留在代碼隱藏。

+0

聽起來像一個樣式觸發器,可以改變模板的setter或者模板選擇器。似乎有點不同尋常的是在屬性更改時更改整個模板(通常您會根據屬性顯示或隱藏模板的元素,並且僅在ContentControl.DataContext的運行時類型發生更改時才更改模板),但沒有更多細節無法判斷。 –

+0

那麼,@Ed,我意識到它可能不完全是類似WPF的(我只是在學習),但正如我所說的,「MStatusDisplaySelector」不是微不足道的,我不明白我如何在xaml中實現它(或相反,它會非常冗長)。例如,其中一個屬性是一個複雜的按位模式,基於此模式,我可能需要顯示圖像,圖像或文本網格,或將其完全隱藏。在代碼隱藏中編寫這樣的代碼很容易,但在xaml中並非如此。 – Zeus

+0

我猜,你可以在價值轉換器中做這個邏輯。當然,您不會嘗試在XAML中編寫該邏輯。無論如何,這聽起來像你認爲這一點。 –

回答

1

添加到您的用戶控件代碼:

protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) 
    { 
     if (e.OldValue != null && e.NewValue != null && e.Property.ToString() == "Title") 
     { 
      System.Diagnostics.Debug.WriteLine(e.Property.ToString() + " > " + e.OldValue.ToString() + " : " + e.NewValue.ToString()); 
      /* You can call your TemplateSelector method here, or put some code here */ 
     } 
     base.OnPropertyChanged(e); 
    } 

在此重寫的方法,你可以檢查這使得這種方法越來越被稱爲Property,並相應地採取適當的措施。

+0

這樣我可以檢測到一個變化。這確實是最簡單的方法。但主要問題是:我應該採取什麼行動?我如何推動我的'ContentPresenter'來刷新它的模板?我可以,可能,刪除'ContentTemplateSelector'聲明並從這個處理程序的代碼中分配'ContentTemplate' ...但是這看起來更加不合WPF對我... – Zeus

+0

@Zeus它不清楚刷新模板。每當綁定到「內容」的屬性改變「綁定」時,都會刷新「內容」,而內容又會調用「TemplateSelector」。因此,您可以在'OnPropertyChanged'方法中更改'ViewModel:bound-property',這會反過來刷新'Content'。 – AnjumSKhan

+0

但綁定目標是'UserControl'本身。換句話說,有效的'.Content = this'(我沒有在上面的原始代碼中分配一個'Name')。如果我在'OnPropertyChanged'強制這個賦值,它不會做任何事情,因爲對象本身沒有改變。只有它的一些屬性。 – Zeus

相關問題