2014-07-02 23 views
0

我必須編寫一個ExtendedStackPanel控件,它具有兩個這樣的依賴屬性。如何定義具有兩個子依賴項屬性的擴展堆棧面板控件

<ExtendedStackPanel IsReadOnly="{Binding Item.IsReadOnly, Mode=OneWay}" > 
    <TemplateTrue> 
         ... control visible when isreadonly is true 
     </TemplateTrue> 
     <TemplateFalse> 
          ... control visible when isreadonly is false 
     </TemplateFalse> 
</ExtendedStackPanel> 

我寫了這個來實現目標,但它不工作。

public class ExtendedStackPanel : StackPanel 
{ 
    public ExtendedStackPanel() 
     : base() 
    { 
     this.Orientation = System.Windows.Controls.Orientation.Vertical; 
    } 
    #region IsReadOnly 
    public bool IsReadOnly 
    { 
     get { return (bool)GetValue(IsReadOnlyProperty); } 
     set { SetValue(IsReadOnlyProperty, value); } 
    } 
    public static readonly DependencyProperty IsReadOnlyProperty = 
     DependencyProperty.Register("IsReadOnly", typeof(bool), 
      typeof(ExtendedStackPanel), new PropertyMetadata(new PropertyChangedCallback(OnReadOnlyChanged))); 

    static void OnReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var visible = (bool)e.NewValue; 
     var control = d as ExtendedStackPanel; 
     if (visible) 
     { 
      control.TemplateTrue.Visibility = Visibility.Visible; 
      control.TemplateFalse.Visibility = Visibility.Collapsed; 
     } 
     else 
     { 
      control.TemplateTrue.Visibility = Visibility.Collapsed; 
      control.TemplateFalse.Visibility = Visibility.Visible; 
     } 

    } 
    #endregion 
    #region TemplateTrue 
    public Control TemplateTrue 
    { 
     get { return (Control)GetValue(TemplateTrueProperty); } 
     set { SetValue(TemplateTrueProperty, value); } 
    } 
    public static readonly DependencyProperty TemplateTrueProperty = 
      DependencyProperty.Register("TemplateTrue", typeof(Control), 
      typeof(ExtendedStackPanel), new PropertyMetadata(new PropertyChangedCallback(OnTemplateTrueChanged))); 

    static void OnTemplateTrueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var control = d as ExtendedStackPanel; 
     control.TemplateTrue.Visibility = control.IsReadOnly ? Visibility.Visible : Visibility.Collapsed; 
    } 
    #endregion 
    #region TemplateFalse 
    public Control TemplateFalse 
    { 
     get { return (Control)GetValue(TemplateFalseProperty); } 
     set { SetValue(TemplateFalseProperty, value); } 
    } 
    public static readonly DependencyProperty TemplateFalseProperty = 
      DependencyProperty.Register("TemplateFalse", typeof(Control), 
      typeof(ExtendedStackPanel), new PropertyMetadata(new PropertyChangedCallback(OnTemplateFalseChanged))); 

    static void OnTemplateFalseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var control = d as ExtendedStackPanel; 
     control.TemplateFalse.Visibility = !control.IsReadOnly ? Visibility.Visible : Visibility.Collapsed; 
    } 
    #endregion 
} 

在我的代碼,我已經把ComboBox控件時IsReadOnly設置爲false,和一個簡單的文本框時,IsReadOnly設置爲true,但運行代碼時不顯示任何內容。 請幫助我。

+0

所有這一切只是選擇一個或其他子控件,取決於綁定的'Item.IsReadOnly'屬性的值?這是用在ItemsControl的ItemTemplate中嗎? – Clemens

+0

是的。我已經使用了一種行爲來直接控制組合框中的只讀狀態,但是當組合框只讀時,可以通過鼠標滾輪或鍵盤箭頭更改值。這就是我開發上述解決方案的原因。 –

+0

但是,爲什麼不只是將DataTemplate與ComboBox和TextBlock相互疊加並根據項目的只讀狀態切換其各自的可見性? – Clemens

回答

0

最後,我選擇使用一個UserControl,其中我放了兩個ContentControl。我寫這個:

public partial class ConditionalControl : UserControl, INotifyPropertyChanged 
{ 
    public ConditionalControl() 
    { 
     InitializeComponent(); 
     this.IsReadOnly = false; 
    } 
    #region IsReadOnly 
    public bool IsReadOnly 
    { 
     get { return (bool)GetValue(IsReadOnlyProperty); } 
     set { SetValue(IsReadOnlyProperty, value); } 
    } 
    public static readonly DependencyProperty IsReadOnlyProperty = 
     DependencyProperty.Register("IsReadOnly", typeof(bool), 
      typeof(ConditionalControl), new PropertyMetadata(new PropertyChangedCallback(OnReadOnlyChanged))); 

    static void OnReadOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var visible = (bool)e.NewValue; 
     var control = d as ConditionalControl;    
     if (visible) 
     { 
      control.TemplateTrueContent.Visibility = Visibility.Visible; 
      control.TemplateFalseContent.Visibility = Visibility.Collapsed; 
     } 
     else 
     { 
      control.TemplateTrueContent.Visibility = Visibility.Collapsed; 
      control.TemplateFalseContent.Visibility = Visibility.Visible; 
     } 

    } 
    #endregion 
    #region TemplateFalse 
    public object TemplateFalse 
    { 
     get { return (object)GetValue(TemplateFalseProperty); } 
     set { SetValue(TemplateFalseProperty, value); } 
    } 
    public static readonly DependencyProperty TemplateFalseProperty = 
      DependencyProperty.Register("TemplateFalse", typeof(object), 
      typeof(ConditionalControl), new PropertyMetadata(new PropertyChangedCallback(OnTemplateFalseChanged))); 

    static void OnTemplateFalseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var control = d as ConditionalControl; 
     control.TemplateFalseContent.Visibility = !control.IsReadOnly ? Visibility.Visible : Visibility.Collapsed; 
     control.OnPropertyChanged("TemplateFalse"); 
    } 
    #endregion 
    #region TemplateTrue 
    public object TemplateTrue 
    { 
     get { return (object)GetValue(TemplateTrueProperty); } 
     set { SetValue(TemplateTrueProperty, value); } 
    } 
    public static readonly DependencyProperty TemplateTrueProperty = 
      DependencyProperty.Register("TemplateTrue", typeof(object), 
      typeof(ConditionalControl), new PropertyMetadata(new PropertyChangedCallback(OnTemplateTrueChanged))); 

    static void OnTemplateTrueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var control = d as ConditionalControl; 
     control.TemplateTrueContent.Visibility = control.IsReadOnly ? Visibility.Visible : Visibility.Collapsed; 
     control.OnPropertyChanged("TemplateTrue"); 
    } 
    #endregion 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string propertyName) 
    { 
     if (propertyName == "TemplateFalse") 
     { 
      this.TemplateFalseContent.Content = this.TemplateFalse; 
     } 
     if (propertyName == "TemplateTrue") 
     { 
      this.TemplateTrueContent.Content = this.TemplateTrue; 
     } 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

希望這會幫助別人。

相關問題