2012-10-25 115 views
0

我正在處理WPF表單設計器,您可以在其中將標籤,文本框,組合框等控件拖放到設計表面,然後通過屬性網格用戶可以爲每個控件設置數據綁定。我有一個要求,顯示那些沒有給定屬性綁定集的控件的紅色背景。基於DependencyProperty綁定的WPF樣式DataTrigger

我最初的想法是創建一個HasBindingConverter,它將調用調用元素本身並檢查它是否綁定到某個屬性。在這種情況下TextBox.TextProperty

public class HasBindingConverter: IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     FrameworkElement fe = value as FrameworkElement; 
     if(fe != null) 
     { 
      Binding binding = BindingOperations.GetBinding(fe, TextBox.TextProperty); 
      return binding != null; 
     } 
     return false; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return null; 
    } 
} 

然後,我添加關聯到TextBox控件類型,我的形式的參考資料部分樣式這是一個用戶控件:

<UserControl.Resources> 
    <Style TargetType="TextBox"> 
     <Style.Resources> 
      <Converters:HasBindingConverter x:Key="HasBindingConv"/> 
     </Style.Resources> 
     <Style.Triggers> 
      <DataTrigger 
      Binding="{Binding, 
      RelativeSource={RelativeSource Self}, 
      Converter={StaticResource HasBindingConv}}" 
      Value="False"> 
       <Setter Property="TextBox.Background" Value="Red" /> 
       </DataTrigger> 
<DataTrigger Binding="{Binding 
      RelativeSource={RelativeSource Self}, 
      Converter={StaticResource HasBindingConv}}" 
      Value="True"> 
       <Setter Property="TextBox.Background" Value="White" /> 
     </Style.Triggers> 
    </Style> 

所以,如果文本框沒有數據綁定集對於TextBox.TextProperty,它會將其背景設置爲紅色。這部分工作正常,問題是當用戶爲此控件設置TextBox.TextProperty綁定時,我的Converter不再被調用,所以背景保持紅色。

任何人都知道如何在設置此控件的綁定後調用觸發器?或者其他任何建議,我可能會以錯誤的方式來解決問題。

謝謝!

回答

1

發生這種情況的原因是,Binding將不會再次作爲源被調用,即一旦它被創建,TextBox本身不會被更改!

假設您專注於TextBox

  1. 所以必須設置爲當前控制容器(Window/UserControl)的Tag屬性。

    myWindow.Tag = FocusManager.GetFocusedElement(myWindow); 
    
  2. 更改與此Binding觸發。

    <DataTrigger 
        Binding="{Binding, 
        Path=Tag, 
        RelativeSource={RelativeSource AncestorType=Window}, 
        Converter={StaticResource HasBindingConv}}" .. > 
    
  3. 刷新的WindowTag財產。

    myWindow.Tag = null; 
    myWindow.Tag = FocusManager.GetFocusedElement(myWindow); 
    
+0

謝謝對於這個建議,現在我需要何時/何時調用步驟1和3? –

+0

步驟1當我放棄我的控制和第3步後,我設置綁定? –

+0

我認爲這是工作!我會稍微等一下,看看別人是否有其他建議,但你的方式似乎清晰和簡單。 @ WPF-it –

0

我找到了另一種方式來解決這個問題。

我創建了一個ControlHasBindingBehavior附加屬性,它最初設置爲false。

public class ControlHasBindingBehavior 
{ 
    #region DependencyProperty HasBinding 

    /// <summary> 
    /// Registers a dependency property as backing store for the HasBinding property 
    /// Very important to set default value to 'false' 
    /// </summary> 
    public static readonly DependencyProperty HasBindingProperty = 
     DependencyProperty.RegisterAttached("HasBinding", typeof(bool), typeof(ControlHasBindingBehavior), 
     new FrameworkPropertyMetadata(false,FrameworkPropertyMetadataOptions.AffectsRender)); 

    /// <summary> 
    /// Gets or sets the HasBinding. 
    /// </summary> 
    /// <value>The HasBinding.</value> 
    public static bool GetHasBinding(DependencyObject d) 
    { 
     return (bool)d.GetValue(HasBindingProperty); 
    } 

    public static void SetHasBinding(DependencyObject d, bool value) 
    { 
     d.SetValue(HasBindingProperty, value); 
    } 

    #endregion 
} 

然後在我的FormDesigner查看我創建了所有的文本框的樣式和觸發所以當框「HasBinding」附加屬性是假的,然後它變成背景爲紅色:

 <Style TargetType="TextBox"> 
     <Style.Triggers> 
      <Trigger Property="Behaviors:ControlHasBindingBehavior.HasBinding" Value="False"> 
       <Setter Property="Background" Value="Red"/> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 

最後,當用戶設置成功綁定一個給定的控制我的附加屬性設置爲「真」:

   ControlHasBindingBehavior.SetHasBinding(SelectedObject,true); 

發生這種情況時我的TextBox。背景變爲白色再次:) 起初,我想樣式觸發應用到一個通用的方式,所有UI元素,FrameworkElements或控制,但看起來這根據this thread

希望有人是不可能發現它有用