【问题标题】:Visibility Binding using DependencyProperty使用 DependencyProperty 的可见性绑定
【发布时间】:2011-04-03 09:44:51
【问题描述】:

下面有一些简单的代码,它使用 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);
            }
        }
    }
}

【问题讨论】:

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


    【解决方案1】:

    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。还应该提到的是,使用“this”作为 ElementName 参数不会像 C# 那样引用相同的“this”。
    • 谢谢!现在这是有道理的。我没有考虑给 Window 起个名字。不幸的是,它似乎并没有解决问题。还在看……
    【解决方案2】:

    您当前的设置方式永远不会将 ShowMoreText 设置为 false。只有当 ToggleButton 的 IsChecked 从 false 变为 true 时,才会调用 Checked 处理程序。反过来,您也需要 Unchecked 的处理程序。处理这种情况的最好方法是在 ToggleButton 上设置一个 Binding,它可以在没有任何事件处理程序的情况下完成这两个操作(使用 Jay 的更改):

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

    【讨论】:

    • 优秀。我没有注意到 Checked 事件仅在它为真时发生。在您的回答和杰伊的回答之间,我已经能够解决这个问题。谢谢。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2013-12-13
      • 2014-08-20
      • 1970-01-01
      • 2011-12-18
      • 2012-02-09
      • 1970-01-01
      • 2010-09-27
      • 2012-07-25
      • 1970-01-01
      相关资源
      最近更新 更多