我是 WPF 开发的新手,但我正在考虑如何用一 block 石头杀死 3 只鸟。 示例:我有一个包含 2 个文本框和 2 个文本 block 的表单。 第一个“鸟”将能够“丰富”一些带有星号的文本 block ,如果它们引用必填字段:
<TextBlock Grid.Row="0" Grid.Column="0" Text="Age" customProperty="Required" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="Foot Size/>
然后 TextBlock 将以不同方式显示其文本,第一个将带有星号,而未定义自定义属性的则不会。
第二只鸟是对文本框的值进行某种验证,如果我理解正确的话,这是通过使用 CustomValidationRule 完成的,我为此实现了一个类:
class AgeController: ValidationRule
{
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
if (value == null)
return new ValidationResult(false, "Null value");
int temp = 1;
Boolean noIllegalChars = int.TryParse(value.ToString(), out temp);
if (temp >= 1)
return new ValidationResult(true, null);
else
return new ValidationResult(false, "Correggi");
}
}
通过将此添加到 textBlox XAML 代码:
<TextBox.Text>
<Binding Path="blabla" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
<Binding.ValidationRules>
<local:AgeController ValidationStep="RawProposedValue" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
这是可行的,但是必填字段和非必填字段的验证过程应该不同:如果是必填字段,空白输入是无效的,但如果是可选的,则空白字段是可以的。 在引用链接到文本框的文本 block 时如何在不指定两个不同的 ValidationRule 的情况下实现这一点?
/tldr:我正在尝试找到一种方法来丰富文本 block ,该文本 block 具有为其文本添加样式的属性(星号或客户想要的任何内容,我只在一个地方修改了丰富修改文本的方式),引用丰富文本 block 的文本框验证将根据丰富的值表现不同。
我希望我没有搞砸解释。
最佳答案
<强>1。 TextBlock 没有 ControlTemplate 属性。所以要求的(*)不能加到TextBlock中
Label 有一个控件模板,可以将焦点放在输入字段上。让我们使用它。
使用 Target 属性在按下 Alt+F 时将焦点传递给 TextBox:
<!-- Prefixing Firstname with _ allows the user to give focus
to the textbox (Target) by pressing Alt + F-->
<local:LabelWithRequiredInfo Content="_Firstname"
IsRequired="false"
Target="{Binding ElementName=textboxFirstname,
Mode=OneWay}" ... />
创建 Label 的子类:LabelWithRequiredInfo,因此可以添加 IsRequired 属性。
(使用 VS 添加新项目/WPF 自定义控件)。
<强>2。为控件创建 IsRequired 依赖属性,以便绑定(bind)起作用 - 我们需要它!
public class LabelWithRequiredInfo : Label
{
public bool IsRequired
{
get { return (bool)GetValue(IsRequiredProperty); }
set { SetValue(IsRequiredProperty, value); }
}
// Using a DependencyProperty as the backing store for IsRequired. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsRequiredProperty =
DependencyProperty.Register("IsRequired", typeof(bool), typeof(LabelWithRequiredInfo), new PropertyMetadata(false));
static LabelWithRequiredInfo()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(LabelWithRequiredInfo), new FrameworkPropertyMetadata(typeof(LabelWithRequiredInfo)));
}
}
<强>3。让我们在 Themes\Generic.xaml 中填充 LabelWithRequiredInfo 模板
(但模板首先在 MainWindow.xaml 中设计,右键单击标签/编辑模板/复制 - 因此它可以可视化 - 然后将模板内容复制到 Generic.xaml 中)
<Style TargetType="{x:Type local:LabelWithRequiredInfo}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:LabelWithRequiredInfo}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<!-- A grid has been added to the template content to have multiple content. -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<!-- The Visibility property has to be converted because it's not a bool but has a Visibility type
The converter (pretty classical) can be found in the attached solution, and is declared in the resource section
The binding is made on a property of the component : IsRequired
-->
<TextBlock Text="(*)"
Visibility="{TemplateBinding IsRequired,Converter={StaticResource booleanToVisibilityConverter}}"
Foreground="Red"
Grid.Column="1"
Margin="5 0"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<强>4。 Generic.xaml 中的转换器声明:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TextboxRequiredMandatoryInput">
<local:BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter"/>
<强>5。考虑到 IsRequired 行为的 ValidationRule 声明:
class RequiredValidationRule : ValidationRule
{
public bool IsRequired { get; set; }
public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
{
var content = value as String;
if (content != null)
{
if (IsRequired && String.IsNullOrWhiteSpace(content))
return new ValidationResult(false, "Required content");
}
return ValidationResult.ValidResult;
}
}
6.并在您发现的绑定(bind)中使用它:
<TextBox x:Name="textboxFirstname" HorizontalAlignment="Left" Height="23" Margin="236,94,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
<TextBox.Text>
<Binding Path="Firstname" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
<Binding.ValidationRules>
<local:RequiredValidationRule IsRequired="true" ValidationStep="RawProposedValue" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
你会在这里找到完整的解决方案:
关于c# - WPF 验证取决于必填/非必填字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33256045/