2012-07-02 150 views
0

我一直在試圖解決這個問題。 :(WPF Validation.HasError設置文本框的邊距

對於一個文本框,我有一個Validation.ErrorTemplate設置與文本框的右側的圖像,同時它有一個驗證錯誤。

這個偉大的工程!但有一兩件事我想這樣做是調整或設置邊距的文本框有錯誤,因此它適合在窗體上的文本框的空間。目前,圖像流出的文本框區域之外。

我真正想要的是帶有錯誤的文本框佔據與textbox相同的空間。

這是我的XAML風格:

<Style TargetType="{x:Type TextBox}"> 
<Style.Resources> 
    <my:TextBoxWidthTransformConverter x:Key="TextBoxWidthTransformConverter"/> 
</Style.Resources> 
<Style.Triggers> 
    <Trigger Property="Validation.HasError" Value="true"> 
    <Setter Property="Foreground" Value="Red"/> 
    <Setter Property="Margin" Value="{Binding Converter={StaticResource TextBoxWidthTransformConverter}, RelativeSource={RelativeSource Self}}"/> 
    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}"/> 
    </Trigger> 
</Style.Triggers> 
<Setter Property="Validation.ErrorTemplate"> 
    <Setter.Value> 
    <ControlTemplate> 
     <StackPanel 
     Margin="{TemplateBinding Margin}" 
     Orientation="Horizontal" 
     RenderOptions.BitmapScalingMode="NearestNeighbor" 
     >    
     <AdornedElementPlaceholder 
      Grid.Column="1" 
      Grid.Row="1" 
      Name="controlWithError" 
      /> 
     <Border Width="2"/> 
     <Image 
      ToolTip="{Binding ElementName=controlWithError, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}" 
      Source="imagepath" 
      /> 
     </StackPanel> 
    </ControlTemplate> 
    </Setter.Value> 
</Setter> 

我使用一個轉換器TextBoxWidthTransformConverter只是爲了看看,如果我能得到一些事情發生,但在此之前我只是在數值使用「0,0,20,0」,無果。轉換器不會觸發,保證金不會改變。我使用Snoop來查看是否可以看到被觸摸或更改的財產,但沒有任何反應。

Margin屬性是無法通過Validation.HasError屬性進行更改的嗎?

任何洞見將是美好的!

謝謝!

回答

0

希望能幫助任何可能遇到這個問題的人。

我仍然不確定爲什麼Margin屬性在Validation.HasError觸發器期間沒有改變,但我發現了一個骯髒的工作。

解決方法是使用IValueConverter設置邊距來劫持寬度屬性與某些事件綁定(TextChanged和Unloading以清除事件)。我保留原來的保證金,在我的情況下,我只是擔心右邊距,通過利用TextBoxes標籤屬性。

public class TextBoxMarginConverter : IValueConverter 
{ 
    private const double TEXTBOX_MARGIN_RIGHT = 25.0; 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value == null) 
     { 
     return double.NaN; 
     } 

     TextBox textBox = value as TextBox; 

     if (textBox == null) 
     { 
     return double.NaN; 
     } 

     if (Validation.GetHasError(textBox)) 
     { 
     this.SetTextBoxMargin(TEXTBOX_MARGIN_RIGHT, textBox); 
     } 

     return textBox.Width; 
    } 

    private void SetTextBoxMargin(double marginRight, TextBox textBox) 
    { 
     if (textBox.Tag == null) 
     { 
     textBox.TextChanged += new TextChangedEventHandler(this.TextBoxTextChanged); 

     textBox.Unloaded += new RoutedEventHandler(this.TextBoxUnloaded); 

     double right = textBox.Margin.Right + marginRight; 

     textBox.Tag = textBox.Margin.Right; 

     textBox.Margin = new Thickness(textBox.Margin.Left, textBox.Margin.Top, right, textBox.Margin.Bottom); 
     } 
    } 

    private void TextBoxUnloaded(object sender, RoutedEventArgs e) 
    { 
     TextBox textBox = sender as TextBox; 

     if (textBox == null) 
     { 
     return; 
     } 

     textBox.TextChanged -= new TextChangedEventHandler(this.TextBoxTextChanged); 

     textBox.Unloaded -= new RoutedEventHandler(this.TextBoxUnloaded); 
    } 

    private void TextBoxTextChanged(object sender, TextChangedEventArgs e) 
    { 
     TextBox textBox = sender as TextBox; 

     if (textBox == null) 
     { 
     return; 
     } 

     if (Validation.GetHasError(textBox)) 
     { 
     this.SetTextBoxMargin(TEXTBOX_MARGIN_RIGHT, textBox); 

     return; 
     } 

     if (textBox.Tag != null) 
     { 
     double tag; 

     double.TryParse(textBox.Tag.ToString(), out tag); 

     textBox.Tag = null; 

     textBox.Margin = new Thickness(textBox.Margin.Left, textBox.Margin.Top, tag, textBox.Margin.Bottom); 
     } 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

在你Validation.ErrorTemplate,轉換器適用於Validation.HasError觸發:

<Style.Triggers> 
    <Trigger Property="Validation.HasError" Value="true"> 
    <Setter Property="Width" Value="{Binding Converter={StaticResource TextBoxMarginConverter}, RelativeSource={RelativeSource Self}}"/> 
    <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}"/> 
    </Trigger> 
</Style.Triggers>