WPF - IsEnabled Привязка к DependencyProperty не работает должным образом - PullRequest
3 голосов
/ 08 июня 2009

У меня есть свойство зависимости, определенное в моем окне, как показано ниже:

public static readonly DependencyProperty IsGenericUserProperty = DependencyProperty.Register("IsGenericUser", typeof (bool), typeof (MainWindow));
public bool IsGenericUser
{
    get { return (bool) GetValue(IsGenericUserProperty); }
    set { SetValue(IsGenericUserProperty, value); }
}

В конструкторе моего окна я установил контекст данных контейнера, удерживающего кнопку:

QuickListButtonsStackPanel.DataContext = this;

Я связываю свойство зависимостей со свойством IsEnabled кнопки:

<Button IsEnabled="{Binding IsGenericUser}" .../>

При запуске IsGenericUser имеет значение true, поэтому кнопка включена. Когда я устанавливаю для IsGenericUser значение false, кнопка отключается. Однако, если я снова сделаю IsGenericUser true, с кнопкой ничего не произойдет и она останется отключенной. Что я делаю не так?

Спасибо!

редактировать: Вот стиль, который я использую с кнопкой. Этот стиль вызывает проблему (если у кнопки нет собственного стиля, он работает нормально):

<Style x:Key="BlackButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <ControlTemplate.Resources>
                    <Storyboard x:Key="MouseOverActivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF2F2F2F"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.1270000" Value="#FF2391FF"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="MouseOverDeactivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="rectangle">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF2391FF"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.2200000" Value="#FF2F2F2F"/>

                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="PressActivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF2391FF"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.1370000" Value="#FF48D6FF"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="PressedDeactivating" FillBehavior="Stop" >
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="rectangle">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FF48D6FF"/>
                            <SplineColorKeyFrame KeyTime="00:00:00.2370000" Value="#FF2391FF"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                    <Storyboard x:Key="DisableActivating">
                        <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
                            <SplineColorKeyFrame KeyTime="00:00:00" Value="#FFA7A7A7"/>
                        </ColorAnimationUsingKeyFrames>
                    </Storyboard>
                </ControlTemplate.Resources>
                <Grid>
                    <Rectangle Stroke="Transparent" RadiusX="5" RadiusY="5" x:Name="rectangle">
                        <Rectangle.Fill>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#FF000000" Offset="0"/>
                                <GradientStop Color="#FF2F2F2F" Offset="1"/>
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True" OpacityMask="{x:Null}"/>
                    <Rectangle Stroke="Transparent" RadiusX="5" RadiusY="5" x:Name="WhiteGlow">
                        <Rectangle.Fill>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#5BFFFFFF" Offset="0"/>
                                <GradientStop Color="#00FFFFFF" Offset="0.5"/>
                            </LinearGradientBrush>
                        </Rectangle.Fill>
                    </Rectangle>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsCancel" Value="False"/>
                    <EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
                    <Trigger Property="IsFocused" Value="True">
                        <Trigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverActivating}" x:Name="MouseOverActivating_BeginStoryboard2"/>
                        </Trigger.ExitActions>
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverActivating}" x:Name="MouseOverActivating_BeginStoryboard1"/>
                        </Trigger.EnterActions>
                    </Trigger>
                    <Trigger Property="IsDefaulted" Value="True"/>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Trigger.ExitActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverDeactivating}" x:Name="MouseOverDeactivating_BeginStoryboard"/>
                        </Trigger.ExitActions>
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource MouseOverActivating}" x:Name="MouseOverActivating_BeginStoryboard"/>
                        </Trigger.EnterActions>
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard x:Name="PressActivating_BeginStoryboard" Storyboard="{StaticResource PressActivating}"/>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <BeginStoryboard x:Name="PressedDeactivating_BeginStoryboard" Storyboard="{StaticResource PressedDeactivating}"/>
                        </Trigger.ExitActions>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Trigger.EnterActions>
                            <BeginStoryboard Storyboard="{StaticResource DisableActivating}" x:Name="DisableActivating_BeginStoryboard"/>
                        </Trigger.EnterActions>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Ответы [ 3 ]

5 голосов
/ 08 июня 2009

Как вы устанавливаете свойство в False / True? Если я скопирую ваш код как есть, он будет работать отлично. Должно быть что-то еще, что вы можете не ожидать, например, анимация на кнопке или что-то, что очищает привязку. Есть ли еще код, который вы можете опубликовать, который может помочь уточнить, что может делать это?

Вот код, который я также тестировал:

<Window x:Class="WpfApplication6.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">
<Grid>
    <StackPanel x:Name="QuickListButtonsStackPanel">
        <Button IsEnabled="{Binding IsGenericUser}"
                Content="Bound Button" />
        <Button Content="Change Binding"
                Click="Button_Click" />
    </StackPanel>
</Grid>

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        QuickListButtonsStackPanel.DataContext = this;
    }
    public static readonly DependencyProperty IsGenericUserProperty =
        DependencyProperty.Register(
            "IsGenericUser",
            typeof(bool),
            typeof(Window1));

    public bool IsGenericUser
    {
        get { return (bool)GetValue(IsGenericUserProperty); }
        set { SetValue(IsGenericUserProperty, value); }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        IsGenericUser = !IsGenericUser;
    }
}

EDIT: Вы также можете добавить текстовое поле, чтобы увидеть, работает ли оно,

<Button x:Name="uiButton"
        IsEnabled="{Binding IsGenericUser}"
        Style="{StaticResource BlackButtonStyle}"
        Content="Bound Button"/>
<TextBlock Text="{Binding ElementName=uiButton, Path=IsEnabled}" />

Похоже, проблема только в раскадровках стиля, если вы добавите это, все равно будет ли показываться, что IsEnabled имеет значение false, когда этого не должно быть?

0 голосов
/ 09 июня 2009

1) Создал новую раскадровку под названием DisableDeactivating и установил FillBehavior = "Stop" (предложение Николаса) 2) Затем добавили BeginStoryboard для DisableDeactivating в Trigger.ExitActions триггера IsEnabled = false.

0 голосов
/ 08 июня 2009

Попробуйте

<Button IsEnabled={Binding Path=IsGenericUser}" ... />

Path= не требуется, но может отличаться.

И, используя this в контексте данных, вы уверены, что это правильно? Разве это не делает сам контроль в контексте. Я не видел остальную часть вашего кода, но это кажется неправильным.

...