为空Multi-Binding时隐藏TextBox而没有焦点

时间:2014-11-27 16:21:39

标签: c# wpf xaml mvvm

我有一个文本框,我试图遵守以下规则:

文本框在有焦点时必须始终可见

文本框必须始终在没有焦点时隐藏

我有一个依赖项属性设置,允许我重新聚焦文本框,以便显示。这适用于单程"因为我可以关注一个折叠的文本框,它会显示出来。但是一旦我将焦点移出文本框(并且它的空白),它就会一直存在。

如果焦点丢失并且它是空的,我怎么能折叠文本框? (注意:我也想显示框,如果输入文本(它被绑定到其他文本框,可能有文本输入,这是双向绑定)。

<Style x:Key="textBoxHider" TargetType="{x:Type TextBox}" BasedOn="{StaticResource storyForgeTextBox}">
    <Style.Triggers>
        <Trigger Property ="IsMouseOver" Value="True">
            <Setter Property= "BorderBrush" Value="LightCyan"/>
            <Setter Property= "BorderThickness" Value="2"/>
        </Trigger>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property= "BorderBrush" Value="LightSkyBlue"/>
            <Setter Property= "BorderThickness" Value="2"/>
        </Trigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="Text" Value=""></Condition>
                <Condition Property="IsFocused" Value="False"></Condition>
            </MultiTrigger.Conditions>
            <MultiTrigger.Setters>
                <Setter Property="Visibility" Value="Collapsed"></Setter>
            </MultiTrigger.Setters>
        </MultiTrigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsFocused" Value="True"></Condition>
            </MultiTrigger.Conditions>
            <MultiTrigger.Setters>
                <Setter Property="Visibility" Value="Visible"></Setter>
            </MultiTrigger.Setters>
        </MultiTrigger>
    </Style.Triggers>
</Style>

编辑:为了清晰起见,我进一步简化了它,它仍然没有崩溃。检查Snoop中的值。当我没有专注/专注时,IsFocused被正确设置为FALSE和TRUE。

<Style x:Key="TextBoxHider" TargetType="{x:Type TextBox}" BasedOn="{StaticResource storyForgeTextBox}">
    <Style.Triggers>
        <Trigger Property ="IsMouseOver" Value="True">
            <Setter Property= "BorderBrush" Value="LightCyan"/>
            <Setter Property= "BorderThickness" Value="2"/>
        </Trigger>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property= "BorderBrush" Value="LightSkyBlue"/>
            <Setter Property= "BorderThickness" Value="2"/>
            <Setter Property="Visibility" Value="Visible"></Setter>
        </Trigger>
        <Trigger Property="IsFocused" Value="False">
            <Setter Property="Visibility" Value="Collapsed"></Setter>
        </Trigger>
    </Style.Triggers>
</Style>

编辑:编辑:我现在难过了。边框画笔设置为RED没问题。所以IsFocused正在被解雇,但它没有崩溃?

<Style x:Key="storyForgeTextBoxHider" TargetType="{x:Type TextBox}" BasedOn="{StaticResource storyForgeTextBox}">
    <Style.Triggers>
        <Trigger Property ="IsMouseOver" Value="True">
            <Setter Property= "BorderBrush" Value="LightCyan"/>
            <Setter Property= "BorderThickness" Value="2"/>
        </Trigger>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property= "BorderBrush" Value="LightSkyBlue"/>
            <Setter Property= "BorderThickness" Value="2"/>
            <Setter Property="Visibility" Value="Visible"></Setter>
        </Trigger>
        <Trigger Property="IsFocused" Value="False">
            <Setter Property="Visibility" Value="Collapsed"></Setter>
            <Setter Property="BorderBrush" Value="Red"></Setter>
        </Trigger>
    </Style.Triggers>
</Style>

3 个答案:

答案 0 :(得分:1)

请检查此代码;我使用了高度和可见性属性;添加代码运行应用程序并根据您的问题尝试建议

操作1:文本框在有焦点时必须始终可见

只需使用'Tab'键即可。当第二个文本框获得焦点时,它将是可见的。当它失去焦点时,它将被折叠。 (我使用了“高度”属性)

操作2:文本框必须始终隐藏,因为它没有焦点并且它是空的

只需从2个可用文本框中删除1个文本框中的文本。当它为空时,第二个文本框将被折叠。 (我使用过“可见性”属性)

XAML代码:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sampleApp="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <sampleApp:TextToVisibilityConverter x:Key="TextToVisibilityConverter"/>
</Window.Resources>
<Grid ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBox x:Name="textBox1" Grid.Row="0" Text="{Binding Text,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" BorderThickness="5" Height="50" Width="300"/>
    <TextBox x:Name="textBox2" Grid.Row="1" Text="{Binding Text,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="300" Visibility="{Binding Text,Converter={StaticResource TextToVisibilityConverter}}"
             BorderThickness="5">
        <TextBox.Style>
            <Style TargetType="TextBox">
                <Style.Triggers>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter Property="Height" Value="50"/>
                    </Trigger>
                    <Trigger Property="IsFocused" Value="False">
                        <Setter Property="Height" Value="0"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>
    <Button Grid.Row="2" VerticalAlignment="Center" Content="Just a Button"/>
</Grid>

C#代码:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private string m_Text = "Hello!!";

    public string Text
    {
        get { return m_Text; }
        set { m_Text = value; OnPropertyChanged("Text"); }
    }

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

public class TextToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            var text = value.ToString();
            if (string.IsNullOrEmpty(text))
            {
                return Visibility.Collapsed;
            }
            else
            {
                return Visibility.Visible;
            }
        }
        else
        {
            return Visibility.Collapsed;
        }

    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

答案 1 :(得分:0)

我猜你在XAML中有这些方面的东西:

<TextBox Style="{StaticResource textBoxHider}" Visibility="Collapsed">
    ...
</TextBox>

触发器不会设置可见性,因为它是直接设置的(在这种情况下是内联的),设计样式设置器不会影响直接设置的属性(内联,作为XAML标记,代码 - 背后)。为了使其工作,您应该通过样式设置初始可见性值,例如:

<TextBox>
    <TextBox.Style>
        <Style TargetType="TextBox" BasedOn="{StaticResource textBoxHider}">
            <Setter Property="Visibility" Value="Collapsed"/>
        </Style>
    </TextBox.Style>
    ...
</TextBox>

答案 2 :(得分:0)

通过代码设置textBox.Visibility = Visibility.Visible后,任何设置visibilty的触发器都将无效。

有关详细信息,请参阅MSDN's Dependency Property Value Precedence,特别是:

  

请谨慎设置具有主题级别的属性的值   触发行为并确保您不会过度干扰   该控件的预期用户体验。