如何使用触发器更改TextBlock的可见性?

22

当我尝试编译以下代码时,我会得到错误信息'Visibility' member is not valid because it does not have a qualifying type name.

我需要做些什么改动,才能在状态为off时使消失?

XAML:

<Window x:Class="TestTrigger123345.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <TextBlock Text="This is a sentence.">
            <TextBlock.Triggers>
                <Trigger Property="{Binding Status}" Value="off">
                    <Setter Property="Visibility" Value="Collapsed"/>
                </Trigger>
            </TextBlock.Triggers>
        </TextBlock>
        <TextBlock Text="{Binding Status}"/>
    </StackPanel>
</Window>

后端代码:

using System.Windows;

namespace TestTrigger123345
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            DataContext = this;
            Status = "off";
        }

        public string Status { get; set; }

    }
}

我改用了DataTrigger和依赖属性,但仍然出现相同的错误:

XAML:

<Window x:Class="TestTrigger123345.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel HorizontalAlignment="Left">
        <TextBlock Text="{Binding Status}">
            <TextBlock.Triggers>
                <DataTrigger Binding="{Binding Status}" Value="off">
                    <Setter Property="TextBlock.Background" Value="Tan"/>
                </DataTrigger>
            </TextBlock.Triggers>
        </TextBlock>
    </StackPanel>
</Window>

后台代码:

using System.Windows;

namespace TestTrigger123345
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            DataContext = this;
            Status = "off";
        }

        #region DependencyProperty: Status
        public string Status
        {
            get
            {
                return (string)GetValue(StatusProperty);
            }
            set
            {
                SetValue(StatusProperty, value);
            }
        }

        public static readonly DependencyProperty StatusProperty =
            DependencyProperty.Register("Status", typeof(string), typeof(Window1),
            new FrameworkPropertyMetadata());
        #endregion


    }
}

我使用了一个具有实现INotifyPropertyChanged的属性状态的ViewModel重新完成了这个项目,但它仍然出现了同样的错误:

WindowViewModel.cs:

using System.ComponentModel;

namespace TestTrigger123345
{
    class WindowViewModel
    {
        #region ViewModelProperty: Status
        private string _status;
        public string Status
        {
            get
            {
                return _status;
            }

            set
            {
                _status = value;
                OnPropertyChanged("Status");
            }
        }
        #endregion

        #region PropertChanged Block
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
        #endregion
    }
}

后端代码:

using System.Windows;

namespace TestTrigger123345
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            WindowViewModel windowViewModel = new WindowViewModel();
            windowViewModel.Status = "off";
            DataContext = windowViewModel;
        }

    }
}

肯定有一种方法可以通过触发器来完成这个任务。

5个回答

60

你需要指定要设置可见性的类型

<Setter Property="FrameworkElement.Visibility" Value="Visible"/>

10
有时为什么不需要类型名就能正常工作,比如 <Button.Triggers><Trigger Property="IsFocused" Value="True"> … 这很令人困惑。 - Martin Konicek
1
因为微软,所以如此。 - Eternal21
一个 DependencyObject 可以通过与父类同名的 DependencyProperty 来“隐藏”它,但是它们在字典中需要有唯一的名称。在这种情况下,“FrameworkElement.” 是字典键的一部分,这就是你需要引用的内容。 - Grault

6
尝试像这样做:

尝试像这样做:

<PasswordBox Name="pbxPassword" />
<TextBox Text="{Binding Password,
                        ElementName=pbxPassword,
                        UpdateSourceTrigger=PropertyChanged}">
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Setter Property="Visibility" Value="Hidden" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsChecked, ElementName=chbShowPassword}" Value="True">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>                  
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>
<CheckBox Name="chbShowPassword">
    Show password
</CheckBox>

2

元素的触发器仅支持EventTrigger,因此无法使用属性触发器(Trigger)。请查看FrameworkElement.Triggers属性。


0

也许您需要实现INotifyPropertyChanged并在状态更改时引发PropertyChange事件?

您可以使用转换器(Converter)将可见性(Visibility)和状态字符串进行转换,而不是使用触发器(Trigger)。


那么我的转换器会接受一个字符串(状态),并返回一个属性可见性吗?还是你的意思是返回整个元素?这在代码中如何实现? - Edward Tanguay
我也使用了ViewModel重新实现了这个功能(见上方代码),但是仍然出现了相同的错误。 - Edward Tanguay

0

它使用DataTrigger和Dependency Property(上面发布的代码)会得到相同的错误。 - Edward Tanguay
我的代码似乎与那篇文章实现方式相同,只是一个DataTrigger,绑定到一个属性,只不过他使用了一个样式,但这不应该有任何影响。 - Edward Tanguay
我也使用了ViewModel重新实现了这个功能(如上所示的代码),但是它仍然出现了相同的错误。可能是与XAML有关,我真的需要一个EventTrigger吗?所有的代码示例(比如您提供的那个)都只是使用DataTrigger并绑定到他们想要检查的属性。 - Edward Tanguay
嘿,Edward,看看你另一个问题的答案吧 :) https://dev59.com/vEfRa4cB1Zd3GeqP_r_e#914825 - Arcturus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接