【问题标题】:Accomplish with Triggers the job of events from a TextBox in WPF从 WPF 中的 TextBox 触发事件的工作来完成
【发布时间】:2011-04-17 17:29:33
【问题描述】:

您好,我正在尝试将我正在做的事情放在代码背后的事件中,该触发器正在应用于文本框的样式的触发器中。我想要的是防止使用背后的代码来做到这一点并使用触发器。有没有办法做到这一点?

我的文本框

<TextBox Name="myTextBox"  Style="{StaticResource txtBoxStyle}"/>

我的风格

<Style x:Key="txtBoxStyle" TargetType="{x:Type TextBox}">
    <Setter Property="Foreground" Value="Silver"/>
    <Setter Property="MaxLength" Value="6"/>
</Style>

代码背后的事件

private void myTextBox_LostFocus(object sender, RoutedEventArgs e)
{
    if (myTextBox.Text.Length == 0)
        myTextBox.Text = "000000";
}

private void myTextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (myTextBox.Text == "000000")
        myTextBox.Clear();
}

private void myTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (!(e.Key >= Key.D0 && e.Key <= Key.D9) && e.Key != Key.Back)
        e.Handled = true;
}

private void myTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    if (myTextBox.Text == "000000")
        myTextBox.Foreground = Brushes.Silver;
    else
    {                
        myTextBox.Foreground = Brushes.Black;

        if(myTextBox.Text.Length == 6)
            myButton.Visibility = Visibility.Visible;
        else
            myButton.Visibility = Visibility.Hidden;
    }
}

提前致谢!

【问题讨论】:

    标签: c# wpf xaml styles


    【解决方案1】:

    编辑:为此逻辑使用触发器不是一个好主意,并且由于其自引用(导致堆栈溢出)而很可能会失败,值转换器也有点问题。要封装复杂的逻辑并通过样式应用它,请使用attached behavior


    <Style TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsFocused, RelativeSource={RelativeSource Self}}" Value="False"/>
                    <Condition Binding="{Binding Text, RelativeSource={RelativeSource Self}}" Value=""/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Text" Value="000000"/>
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding IsFocused, RelativeSource={RelativeSource Self}}" Value="True"/>
                    <Condition Binding="{Binding Text, RelativeSource={RelativeSource Self}}" Value="000000"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="Text" Value=""/>
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
            <Trigger Property="Text" Value="000000">
                <Setter Property="Foreground" Value="Silver"/>
            </Trigger>
        </Style.Triggers>
        <!-- If (Text != "000000") Foreground = Brushes.Black -->
        <Setter Property="Foreground" Value="Black"/>
    </Style>
    

    设置按钮可见性的逻辑不应以这种样式处理,而应由按钮处理。无法翻译按键事件。

    按钮样式:

    <Style TargetType="{x:Type Button}">
        <Setter Property="Visibility" Value="Hidden"/> <!-- Normal state -->
        <Style.Triggers>
            <DataTrigger Binding="{Binding Text.Length, ElementName=myButton}" Value="6">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
    

    【讨论】:

    • 如果我这样做 &lt;Setter Property="Text" Value="000000"/&gt; 有默认设置器(没有触发器),当 TextBox 获得焦点给我这个异常时 Text' Storyboard.TargetProperty 路径包含不可动画属性'Text'。。你能解释一下为什么吗?
    • 对,你不能动画它;无论如何都不需要使用动画,因为我们处理的是状态,而不是事件。我将答案更改为使用应该工作并产生相同结果的设置器。
    • 好吧,这很不幸,但这可能是您可以使用样式获得的最接近的效果。我自己可能不会这样做,基本上你只是希望一个空字符串显示为 6 个零,因为我会使用 ValueConverter 的绑定。
    • 实际上这对我来说会导致堆栈溢出异常。基本上,您永远不应该使用条件是触发器触发时您将设置的属性的触发器。
    • 如果我使用 Text="" 对我来说也是如此,但我尝试使用它并使用 Text="{x:Null}" 但它们都不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多