使用DependencyProperty进行可见性绑定

时间:2010-08-24 20:18:41

标签: c# wpf data-binding dependency-properties

下面我有一些简单的代码,它使用ToggleButton.IsChecked属性来设置TextBlock的可见性。它工作正常。由于这不适合我的程序结构,我试图将另一个TextBlock的可见性绑定到“this”的DependencyProperty。编译很好,但没有效果。我做错了什么,只是不确定是什么。

XAML

<Window x:Class="ToggleButtonTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Width="200" Height="100">
<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
<StackPanel>
    <ToggleButton x:Name="toggleButton" Content="Toggle"
                  IsChecked="True" Checked="toggleButton_Checked"/>
    <TextBlock Text="Some Text"
               Visibility="{Binding IsChecked, 
               ElementName=toggleButton,
               Converter={StaticResource BooleanToVisibilityConverter}}"/>
    <TextBlock Text="More Text"
               Visibility="{Binding ShowMoreText, 
               ElementName=this, 
               Converter={StaticResource BooleanToVisibilityConverter}}"/>
</StackPanel>
</Window>

C#

using System.Windows;

namespace ToggleButtonTest
{
    public partial class MainWindow : Window
    {
        static MainWindow()
        {
            FrameworkPropertyMetadata meta = 
                new FrameworkPropertyMetadata(true,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault);

            ShowMoreTextProperty = 
                DependencyProperty.Register("ShowMoreText", 
                typeof(bool), typeof(MainWindow), meta);
        }

        public MainWindow()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty ShowMoreTextProperty;
        public bool ShowMoreText
        {
            get
            {
                return (bool)GetValue(ShowMoreTextProperty);
            }
            set
            {
                SetValue(ShowMoreTextProperty, value);
            }
        }

        private void toggleButton_Checked(object sender, RoutedEventArgs e)
        {
            ShowMoreText = toggleButton.IsChecked.Value;
        }
    }
}

编辑:

有了这个回答,我想发布我的工作代码......

XAML

<Window x:Class="ToggleButtonTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Width="200" Height="100"
    Name="thisWindow">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </Window.Resources>
    <StackPanel>
        <ToggleButton x:Name="toggleButton" 
                Content="Toggle"
                IsChecked="{Binding Path=ShowMoreText, ElementName=thisWindow}"/>
        <TextBlock Text="More Text"
                   Visibility="{Binding Path=ShowMoreText, 
                   ElementName=thisWindow,
                   Converter={StaticResource BooleanToVisibilityConverter}}"/>
    </StackPanel>
</Window>

C#

using System.Windows;

namespace ToggleButtonTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty ShowMoreTextProperty =
            DependencyProperty.Register("ShowMoreText", typeof(bool),
            typeof(MainWindow), new FrameworkPropertyMetadata(true,
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public bool ShowMoreText
        {
            get
            {
                return (bool)GetValue(ShowMoreTextProperty);
            }
            set
            {
                SetValue(ShowMoreTextProperty, value);
            }
        }
    }
}

3 个答案:

答案 0 :(得分:11)

ElementName必须是元素名称。 this不会飞。幸运的是,这里有MainWindow类型的元素,其中包含ShowMoreText属性:根Window元素。

Window提供一个名称,并将其用作ElementName,如下所示:

<Window x:Class="ToggleButtonTest.MainWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Title="MainWindow" Width="200" Height="100"
     x:Name="thisWindow">
<Window.Resources>
     <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
<StackPanel>
     <ToggleButton x:Name="toggleButton" Content="Toggle"
                        IsChecked="True" Checked="toggleButton_Checked"/>
     <TextBlock Text="Some Text"
                    Visibility="{Binding IsChecked, 
                    ElementName=toggleButton,
                    Converter={StaticResource BooleanToVisibilityConverter}}"/>
     <TextBlock Text="More Text"
                    Visibility="{Binding ShowMoreText, 
                    ElementName=thisWindow, 
                    Converter={StaticResource BooleanToVisibilityConverter}}"/>
</StackPanel>
</Window>

请注意,您可以使用RelativeSource Self执行相同操作,但我更喜欢上述方法。

答案 1 :(得分:2)

目前设置它的方式不会将ShowMoreText设置为false。仅当ToggleButton的IsChecked从false更改为true时,才会调用Checked处理程序。另外,你也需要一个Unchecked的处理程序。处理这种情况的最好方法是在ToggleButton上设置一个Binding,它将在没有任何事件处理程序的情况下完成(使用Jay的更改):

IsChecked="{Binding Path=ShowMoreText, ElementName=thisWindow}"

答案 2 :(得分:1)

为您的窗口命名并将ElementName设置为该名称,而不是使用“this”。