0

我正在尝试在我的表单上动态更改我的标签样式。我想要的行为是:例如,每当一个名为“txtName”的文本框获得焦点时,它应该搜索一个名为“lblName”的标签控件并将其 FontWeight 属性更改为“Bold”。

对于名为“txtBirthday”的文本框和名为“lblBirthday”的标签也是如此,其中“txt”代表文本框,lbl 代表标签。

每个文本框都有一个名称和一个前缀“txt”和一个前缀“lbl”作为其相应标签,但如果文本框没有找到对应的标签,它应该什么都不做。

换句话说,每次文本框关注表单时,它应该搜索标签“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>
4

2 回答 2

0

正如上面评论中提到的,作为应用视觉行为基础的搜索和模式匹配元素名称的技术并不可靠。例如,当您打错字并使用“lbel”而不是“lbl”时会发生什么?或者,如果您后来决定将所有内容替换LabelsTextBlocks- 您是否仍使用前缀“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>

希望这可以帮助!

于 2011-12-18T14:40:39.693 回答
0

您可以让所有 gotfocus 参加同一个活动。发件人被传递给事件,因此您可以获得发件人的姓名。在后面的代码中,您可以使用 XAML 中不可用的变量和逻辑。

于 2011-12-18T15:43:18.780 回答