这是在这里,所以我的第一个问题......我已经准备了很长时间,从来没有需要寻求帮助,因为我经常发现我所需要的,但我有一个艰难的时间与这一个...
我工作的一个工具套件在WPF。 我创建了一些用户控制如下:
- LabelTextBox(标签左边和文本框右侧)
- LabelTextBoxToggle(LabelTextBox左侧和复选框右侧)
- LabelTextBoxBrowseFile(LabelTextBox在左边,浏览右边文件按钮 )
我使用依赖属性绑定我需要的所有特性,它们都做工精细。 我跑进最近越来越ValidationRules的问题在基础文本框我LabelTextBox使用时,这些规则适用于LabelTextBoxToggle和LabelTextBoxBrowseFile用户控件正常工作,因为我必须向下绑定,才能在LabelTextBox更新控制2倍的水平。 我可以得到验证规则运行,但我不能让TextBox控件进行相应的更新背景色当发现错误时,像我这样做的时候是不是嵌套在其他用户控制LabelTextBox。
所以,这里是我下面的代码:
用于文本框样式:
<!-- TextBox Default Style, Supports Validation Rules -->
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="{StaticResource TextBoxBGDefault}" />
<Style.Triggers>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="Background" Value="{StaticResource TextBoxBGHasFocus}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{StaticResource TextBoxBGHasFocus}" />
</Trigger>
<DataTrigger Binding="{Binding Path=(Validation.HasError)}" Value="true">
<Setter Property="Background" Value="{StaticResource TextBoxBGHasError}" />
<Setter Property="BorderBrush" Value="Firebrick" />
<Setter Property="BorderThickness" Value="1.5" />
<Setter Property="ToolTipService.InitialShowDelay" Value="2" />
<Setter Property="ToolTip" Value="{Binding Path=(Validation.Errors)[0].ErrorContent}" />
</DataTrigger>
</Style.Triggers>
</Style>
LabelTextBox.xaml:
<Grid x:Name="LayoutRoot" DataContext="{Binding ElementName=ControlRoot, Mode=OneWay, ValidatesOnDataErrors=True}">
<Grid.RowDefinitions>
<RowDefinition Height="24" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label
x:Name="NameLabel"
Width="{Binding Path=LabelWidth, Converter={StaticResource WidthToAutoConverter}}"
Margin="0"
HorizontalAlignment="{Binding Path=HorizontalContentAlignment}"
HorizontalContentAlignment="{Binding Path=LabelHAlign, Converter={StaticResource valueToStringConverter}}"
VerticalContentAlignment="Center"
Content="{Binding Path=LabelContent}"
Padding="10,2,5,2" />
<TextBox
x:Name="ValueTextBox"
Grid.Column="1"
KeyDown="TextBox_KeyDown_Enter"
Padding="5,0"
Text="{Binding TextBoxContent, Mode=TwoWay}"
TextChanged="TextBox_TextChanged" VerticalContentAlignment="Center" Height="22" VerticalAlignment="Center" />
<TextBlock
x:Name="ErrorMsgTextBlock"
Grid.Row="1"
Grid.Column="1"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Style="{DynamicResource ValidationErrorLabel}"
Text="{Binding Path=(Validation.Errors)[0].ErrorContent, ElementName=ControlRoot}"
Visibility="{Binding Path=(Validation.HasError), Converter={StaticResource BooleanToVisibilityConverter}, ElementName=ControlRoot, Mode=OneWay}" TextWrapping="Wrap" />
</Grid>
LabelTextBoxBaseClass:
#region TextBox Dependency Properties
public string TextBoxContent
{
get { return (string)GetValue( TextBoxContentProperty ); }
set { SetValue( TextBoxContentProperty, value ); }
}
public static readonly DependencyProperty TextBoxContentProperty =
DependencyProperty.Register( "TextBoxContent"
, typeof( string )
, typeof( LabelTextBoxBaseClass ), new PropertyMetadata( "" )
);
LabelTextBoxToggle.xaml:
<!-- This is the nested UserControl -->
<local:LabelTextBox
x:Name="LTBControl"
Margin="0"
VerticalContentAlignment="Center"
IsEnabled="{Binding Path=IsChecked, ElementName=ToggleCheckBox}"
LabelContent="{Binding Path=LabelContent}"
LabelHAlign="{Binding Path=LabelHAlign}"
LabelWidth="{Binding Path=LabelWidth}"
RaiseEnterKeyDownEvent="{Binding RaiseEnterKeyDownEvent, Mode=TwoWay}"
RaiseTextChangedEvent="{Binding RaiseTextChangedEvent, Mode=TwoWay}"
TextBoxContent="{Binding Path=TextBoxContent, Mode=TwoWay}" />
<CheckBox
x:Name="ToggleCheckBox"
Grid.Column="1"
Margin="5,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Click="ToggleCheckBox_Click"
IsChecked="{Binding CheckBoxChecked, Mode=TwoWay}" />
MaterialBuilder.xaml:
<UserControl.Resources>
<BindingGroup x:Key="SRBindingGroup" Name="PropertiesBindingGroup">
<BindingGroup.ValidationRules>
<local:AddMaterialRule ValidationStep="ConvertedProposedValue" />
</BindingGroup.ValidationRules>
</BindingGroup>
<srvalidators:StringNullOrEmptyValidationRule x:Key="stringNullOrEmptyValidationRule" ErrorMessage="Custom Dir cannot be null!" />
<srconverters:ListToStringConverter x:Key="ListToStringConverter" />
<srconverters:ListToStringConverter x:Key="listToStringConverter" />
<sys:String x:Key="newLine">\n</sys:String>
</UserControl.Resources>
<StackPanel x:Name="spSetup">
<!-- This contains a nested UserControl (LabelTextBox), and I can't get its TextBox background to change color, I just get the red border around the whole control on Validation Errors. -->
<srcontrols:LabelTextBoxBrowseFile
x:Name="ltbMaterialBlueprint"
Height="Auto"
Margin="0,5"
LabelContent="Material Blueprint:"
LabelWidth="120"
LostFocus="ltbMaterialBlueprint_UpdateUI"
OnButtonClick="ltbMaterialBlueprint_UpdateUI"
OnTextBoxEnterKeyDown="ltbMaterialBlueprint_UpdateUI"
TextBoxContent="{Binding MaterialBlueprintFilePath, Mode=TwoWay}">
<srcontrols:LabelTextBoxBrowseFile.TextBoxContent>
<Binding
Mode="TwoWay"
Path="CustomDirName"
UpdateSourceTrigger="PropertyChanged"
ValidatesOnDataErrors="True">
<Binding.ValidationRules>
<srvalidators:StringNullOrEmptyValidationRule ErrorMessage="Custom Dir cannot be empty!" />
</Binding.ValidationRules>
</Binding>
</srcontrols:LabelTextBoxBrowseFile.TextBoxContent>
</srcontrols:LabelTextBoxBrowseFile>
<!-- Here I use the base LabelTextBox control by itself and everything works as intended. The TextBox's background color changes to red on Validation Errors. -->
<srcontrols:LabelTextBox
x:Name="ltbMaterialName"
Margin="0,5,10,5"
LabelContent="Name:"
LabelWidth="60"
OnTextBoxTextChange="ltbMaterialName_Validate"
RaiseEnterKeyDownEvent="True"
RaiseTextChangedEvent="True">
<!-- Set-up the TextBox Content to use the ValidationRule by passing this GroupBox's BindingGroup resource as a parameter -->
<srcontrols:LabelTextBox.TextBoxContent>
<Binding
Mode="TwoWay"
Path="MaterialName"
UpdateSourceTrigger="Explicit"
ValidatesOnDataErrors="True">
<Binding.ValidationRules>
<local:AddMaterialRule
BGroup="{StaticResource SRBindingGroup}"
CheckForDuplicates="True"
CheckForEmptyName="True"
IsMaterialName="True"
ValidationStep="ConvertedProposedValue" />
</Binding.ValidationRules>
</Binding>
</srcontrols:LabelTextBox.TextBoxContent>
</srcontrols:LabelTextBox>
</StackPanel>
我知道这可能是一个DataContext的问题,但不同于其他控件和依赖属性,我无法弄清楚如何使基本用户控件UI元素更新它们的外观时发现验证错误。 下面是我的意思是一些图片:
工作文本框(这里使用LabelTextBox控制):
工作文本框示例
残破的文本框(这里使用,嵌套LabelTextBox LabelTextBoxToggle控制):
破碎的文本框(嵌套在用户控件)
任何帮助或建议十分欢迎,当然! 谢谢你的时间!