views:

2276

answers:

4

When I try to compile the following code, I get the error 'Visibility' member is not valid because it does not have a qualifying type name.

What do I have to change so that I can make the TextBlock disappear when Status=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>

Code Behind:

using System.Windows;

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

        public string Status { get; set; }

    }
}

I changed to DataTrigger and Dependency Properties and it gets the same error:

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>

Code Behind:

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


    }
}

I redid this with a ViewModel that has a property Status that implements INotifyPropertyChanged, and it gets that same error:

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
    }
}

Code Behind:

using System.Windows;

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

    }
}

Surely there is a way to do this with a trigger somehow.

+1  A: 

Maybe you need to implement INotifyPropertyChanged and raise PropertyChange when Status change ?

Instead of using a trigger, you can use a Converter between Visibility and your Status string.

rockeye
I vote for using a Converter.
gcores
so my converter would take a string (status) and return a property visibility? or do you mean return the whole element? how would that be implemented in code?
Edward Tanguay
I also reimplemented this with a ViewModel (code above) and it gets the same error.
Edward Tanguay
A: 

For Bindings use DataTrigger, for properties you can use Trigger.. Also make sure the Status Property notifies ;) Either make it a dependency property or use the INotifyPropertyChanged interface.

DataTrigger on MSDN

Nice article how to combine all these trigger goodness

Arcturus
It gets the same error with DataTrigger and a Dependency Property (posted code above).
Edward Tanguay
My code seems to be implemented the same as that article, simply a DataTrigger, binding to a property, just that he uses a style but that shouldn't make any difference.
Edward Tanguay
I also reimplemented this with a ViewModel (code above) and it gets the same error. It must be something with the XAML, do I really need a EventTrigger? All the code examples (like the one you provided) simply use DataTrigger and bind to the property that they want to check.
Edward Tanguay
Hey Edward, see the answer to your other question :) http://stackoverflow.com/questions/914806/how-can-i-get-a-trigger-to-change-the-color-of-a-textblock-based-on-a-datacontext/914825#914825
Arcturus
A: 

The answer to this is to use a style as explained here.

Edward Tanguay
+7  A: 

You need to specify the Type on which the visibility should be set

<Setter Property="FrameworkElement.Visibility" Value="Visible"/>
Will Perry
Why does it sometimes work without the Type name? Like <Button.Triggers><Trigger Property="IsFocused" Value="True"> ... This is confusing...
Martin Konicek