Привязка видимости с использованием DependencyProperty - PullRequest
1 голос
/ 25 августа 2010

Ниже приведен простой код, который использует свойство ToggleButton.IsChecked для установки видимости TextBlock.Работает нормально.Так как это не совсем соответствует структуре моей программы, я пытаюсь связать видимость другого TextBlock с DependencyProperty «this».Компилируется нормально, но не дает никакого эффекта.Я делаю что-то не так, просто не знаю, что.

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 ]

11 голосов
/ 25 августа 2010

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, но я предпочитаю метод выше.

2 голосов
/ 25 августа 2010

То, как вы его настроили в настоящее время, никогда не установит для ShowMoreText значение false.Обработчик Checked будет вызываться только тогда, когда IsChecked в ToggleButton изменяется с false на true.Чтобы также пойти другим путем, вам нужен обработчик для Unchecked.Лучший способ справиться с этой ситуацией - вместо этого установить Binding на ToggleButton, который будет обходиться без обработчиков событий (используя изменения Джея):

IsChecked="{Binding Path=ShowMoreText, ElementName=thisWindow}"
1 голос
/ 25 августа 2010

Дайте вашему окну имя и присвойте ему имя ElementName вместо использования «this».

...