我正在尝试在表单上动态更改标签样式。 我想要的行为是:每当一个名为'txtName'的文本框获得Focused时,它应该搜索名为'lblName'的标签控件并将其FontWeight属性更改为“Bold”。
名为'txtBirthday'的文本框和名为'lblBirthday'的标签相同,其中'txt'代表TextBox,lbl代表Label。
每个文本框的对应标签都有一个NAME和一个前缀“txt”和一个前缀“lbl”,但如果文本框找不到对应的标签,它就什么都不做。
换句话说,每当Textbox聚焦于表单时,它应该为其描述搜索标签“Responsable”并高亮显示它(将其字体粗细改为粗体),这样表单将更加用户友好。这样用户就不会混淆他输入的文本框。
我有一个和平的代码可能是一个很好的起点,但我不知道如何使用非静态控件名称。
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<!-- Here is how we bind to another control's property -->
<DataTrigger Binding="{Binding IsFocused, ElementName=txtUser}" Value="True">
<Setter Property="FontWeight" Value="Bold" />
<!-- Here is the 'override' content -->
</DataTrigger>
</Style.Triggers>
</Style>
答案 0 :(得分:0)
正如上面的评论中所提到的,搜索和模式匹配元素名称作为应用视觉行为的基础的技术并不健全。例如,当你输入错字并使用“lbel”而不是“lbl”时会发生什么?或者如果您以后决定用Labels
替换所有TextBlocks
会发生什么 - 您是否仍然使用前缀“lbl”注释其名称以保留行为?使用代码更改视觉效果的另一个缺点 - 现在通过单独阅读XAML来理解UI的行为变得更加困难,因为属性在幕后被更改。 WPF有许多内置方法,应该优先于这种方法。如果您对替代实施感兴趣,请问我们在这里提供帮助:)
话虽如此,如果必须使用此方法,那么您的附加行为将如下所示:
<强> C#强>
public static class FontWeightFocusedHelper
{
private static readonly List<Label> Labels = new List<Label>();
public static void SetChangeFontWeightOnTextBoxFocused(Label label, bool value)
{
label.SetValue(ChangeFontWeightOnTextBoxFocusedProperty, value);
}
public static bool GetChangeFontWeightOnTextBoxFocused(Label label)
{
return (bool) label.GetValue(ChangeFontWeightOnTextBoxFocusedProperty);
}
public static readonly DependencyProperty ChangeFontWeightOnTextBoxFocusedProperty =
DependencyProperty.RegisterAttached("ChangeFontWeightOnTextBoxFocused", typeof (bool),
typeof (FontWeightFocusedHelper),
new FrameworkPropertyMetadata(OnChangeFontWeightOnTextBoxFocusedPropertyChanged));
private static void OnChangeFontWeightOnTextBoxFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBox)
{
var textBox = (TextBox) d;
// Make sure to use a WeakEventManager here otherwise you will leak ...
textBox.GotFocus += OnTextBoxGotFocusChanged;
textBox.LostFocus += OnTextBoxLostFocusChanged;
return;
}
if (d is Label)
{
// Make sure to store WeakReferences here otherwise you will leak ...
Labels.Add((Label)d);
return;
}
throw new InvalidOperationException("ChangeFontWeightOnTextBoxFocused can only be set on TextBox and Label types.");
}
private static void OnTextBoxLostFocusChanged(object sender, RoutedEventArgs e)
{
SetMatchingLabelFontWeight(sender as TextBox, FontWeights.Regular);
}
private static void OnTextBoxGotFocusChanged(object sender, RoutedEventArgs e)
{
SetMatchingLabelFontWeight(sender as TextBox, FontWeights.Bold);
}
private static void SetMatchingLabelFontWeight(TextBox textBox, FontWeight fontWeight)
{
if (textBox != null)
{
// Suggest adding a property for LabelPrefix and TextBoxPrefix too, use them here
var label = Labels.Where(l => !String.IsNullOrEmpty(l.Name))
.Where(l => l.Name.Replace("lbl", "txt") == textBox.Name)
.FirstOrDefault();
if (label != null)
{
label.FontWeight = fontWeight;
}
}
}
}
<强> XAML 强>
<StackPanel >
<StackPanel.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="l:FontWeightFocusedHelper.ChangeFontWeightOnTextBoxFocused" Value="True" />
</Style>
<Style TargetType="{x:Type Label}">
<Setter Property="l:FontWeightFocusedHelper.ChangeFontWeightOnTextBoxFocused" Value="True" />
</Style>
</StackPanel.Resources>
<StackPanel Orientation="Horizontal">
<Label x:Name="lblOne" VerticalAlignment="Center" Content="First Name"/>
<TextBox x:Name="txtOne" Width="300" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label x:Name="lblTwo" VerticalAlignment="Center" Content="Last Name" />
<TextBox x:Name="txtTwo" Width="300" VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
希望这有帮助!
答案 1 :(得分:0)
你可以让所有的焦点都去同一个活动。发件人被传递给事件,因此您可以获取发件人的姓名。在后面的代码中,您可以使用XAML中不可用的变量和逻辑。