2011-07-27 20 views
1

對於可怕的問題標題,我不知道如何表達這一點,隨時發表評論。UserControl with Dependancy Properties取代類似控件的重複設置

我正在使用MVVM模式的WPF桌面應用程序。我有我的視圖模型文本字段的大量,所有這些我想用下面的模式(大大簡化)顯示:

<StackPanel Orientation="Vertical"> 
    <StackPanel.Style> 
     <Style TargetType="{x:Type StackPanel}"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Path=SomePredicate}" Value="False"> 
        <Setter Property="Visibility" Value="Collapsed"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </StackPanel.Style> 

    <Label Content="SomeHeader:"/> 

    <TextBlock Text="{Binding Path=SomeText}" /> 

</StackPanel> 

顯示屏總是包括:

  • 謂語爲確定是否應顯示StackPanel
  • 用作標題文本的字符串。這可以在XAML中設置,它不具有來自於視圖模型
  • 綁定到TextBlock文本字符串在視圖模型

我真的喜歡能夠定義這些是這樣的:

<MyHeaderedTextBlockControl Text="{Binding Path=SomeText}" 
          Header="SomeHeader:" 
          Predicate="{Binding SomePredicate}"/> 

可以這樣做嗎?我試圖用UserControl做,但不知道我在做什麼。

的結合模式仍然工作,即如果Text結合這對我來說重要的是在OneWayTwoWay模式下,當Text財產上的視圖模型提出了OnPropertyChangedTextBlock應該更新。

我也不喜歡爲每個這樣的文本屬性做一個View和ViewModel的想法,因爲那麼我必須創建這些ViewModels並將它們連接起來進行更新等。我想要一個我可以實現的解決方案視圖,理想情況下ViewModel甚至不應該知道它。

+0

我不知道這行:「我想要一個解決方案,我可以在View中實現,理想情況下ViewModel甚至不應該知道它。」無論如何,您需要在viewmodel中創建文本,標題,謂詞屬性。 – anivas

+0

@anivas是的,當然,但那些屬性已經存在。 ViewModel公開了謂詞的布爾屬性和Text的String屬性。我將在每次構建這樣的構造時在視圖的XAML中定義標題。 –

+0

如果你有很多這樣的文本框(我希望你有一個文本,頭文件和布爾值的集合),你可以用這些屬性作爲控件的依賴項屬性創建一個usercontrol,你可以用datatemplate創建一個itemscontrol。你卡在哪裏? – anivas

回答

2

隨着用戶控件,你在代碼中定義依賴屬性,並將其通過結合轉發到「模板」,例如:

<UserControl x:Class="Test.UserControls.HeaderedTextBlock" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      Name="control"> 
    <StackPanel Orientation="Vertical"> 
     <StackPanel.Style> 
      <Style TargetType="{x:Type StackPanel}"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding Predicate, ElementName=control}" Value="False"> 
         <Setter Property="Visibility" Value="Collapsed" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </StackPanel.Style> 
     <Label Content="{Binding Header, ElementName=control}" /> 
     <TextBlock Text="{Binding Text, ElementName=control}" /> 
    </StackPanel> 
</UserControl> 
namespace Test.UserControls 
{ 
    public partial class HeaderedTextBlock : UserControl 
    { 

     public static readonly DependencyProperty HeaderProperty = 
      DependencyProperty.Register("Header", typeof(string), typeof(HeaderedTextBlock), new UIPropertyMetadata(null)); 
     public string Header 
     { 
      get { return (string)GetValue(HeaderProperty); } 
      set { SetValue(HeaderProperty, value); } 
     } 

     public static readonly DependencyProperty PredicateProperty = 
      DependencyProperty.Register("Predicate", typeof(bool), typeof(HeaderedTextBlock), new UIPropertyMetadata(false)); 
     public bool Predicate 
     { 
      get { return (bool)GetValue(PredicateProperty); } 
      set { SetValue(PredicateProperty, value); } 
     } 

     public static readonly DependencyProperty TextProperty = 
      DependencyProperty.Register("Text", typeof(string), typeof(HeaderedTextBlock), new UIPropertyMetadata(null)); 
     public string Text 
     { 
      get { return (string)GetValue(TextProperty); } 
      set { SetValue(TextProperty, value); } 
     } 

     public HeaderedTextBlock() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

將這樣的事情對你的工作?

+0

這絕對是完美的,非常棒!非常感謝! –

+0

很高興幫助:) –

相關問題