我是WPF发展的新手,但我正在考虑如何用一块石头杀死3只鸟。示例:我有一个带有2个TextBox和2个TextBlocks的表单。如果第一个“鸟”引用了必填字段,则将能够用星号“丰富”某些文本块:
<TextBlock Grid.Row="0" Grid.Column="0" Text="Age" customProperty="Required" /> <TextBlock Grid.Row="1" Grid.Column="0" Text="Foot Size/>
然后,TextBlocks将以不同的方式显示其文本,第一个将带有星号,而未定义自定义属性的文本将不会。
第二个问题是对文本框的值进行某种验证,如果我正确理解的话,可以通过使用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>
但这有效,但对于必填字段和非必填字段,验证过程应该有所不同:如果需要,则空白输入无效,但如果可选,则空白字段可以。如何在引用链接到文本框的文本块时不指定两个不同的ValidationRule的情况下实现此目标?
/ tldr:我正在尝试寻找一种方法,使用属性为其文本添加样式的属性来丰富文本块(星号或客户端想要的任何内容,我修改了如何在一个地方修改扩展文本),文本框的验证基于丰富的值,引用丰富的文本块的行为将有所不同。
我希望我不会弄乱解释。
1. TextBlock没有ControlTemplate属性。因此不能将所需的(*)添加到TextBlock
Label具有控件模板,可以将焦点放在输入字段上。让我们使用它。
按下Alt + F时使用Target属性将焦点传递到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依赖项属性,以便绑定可以工作-我们需要它!
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.在发现的绑定中使用它:
<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>
您将在此处找到完整的解决方案:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句