2011-12-09 4 views
4

Iは、StaticResourceとして格納IsTrueの性質を持つクラスMyBoolのインスタンスを有します。また、IsCheckedプロパティを持つCheckBoxをクラスのインスタンスにバインドしています。ストーリーボードを介して変更する場合、データバインディングは更新されませんか?

{Binding IsTrue, Mode=TwoWay, Source={StaticResource MyBoolInstance}} 

正常に動作します。チェックボックスのチェックプロパティを変更すると、MyBoolのインスタンスも更新され、その逆もあります。私はを通じてストーリーボード

<Storyboard x:Key="ColourToggle"> 
    <ObjectAnimationUsingKeyFrames 
     Storyboard.TargetProperty="IsChecked" 
     Storyboard.TargetName="ThisCheckBox"> 
    <DiscreteObjectKeyFrame KeyTime="0"> 
     <DiscreteObjectKeyFrame.Value> 
      <System:Boolean>True</System:Boolean> 
     </DiscreteObjectKeyFrame.Value> 
    </DiscreteObjectKeyFrame> 
    </ObjectAnimationUsingKeyFrames> 
</Storyboard> 

プロパティIsTrue MyBoolのインスタンスのをチェックボックスのにisCheckedプロパティを操作する場合

しかし、更新されません!

提案や回避方法はありますか?ここで

+0

しかし 'ThisCheckBox.IsChecked'特性が変化するのでしょうか? 'Storyboard'を使って実際に何を達成しようとしていますか? –

+0

そうです。私の考え方はちょっと間違っています。ストーリーボードを使ってチェックボックスのIsCheckedプロパティを変更しようとしています。バインドされたオブジェクトも変更されることを望みます。 –

+0

'IsChecked'をアニメーションで設定すると、バインドをオーバーライドします。 CheckBox自体ではなく、バインディングソースを変更する必要があります。 – icebat

答えて

3

は完全にあなたの問題を再現する例です。

MyBoolINotifyPropertyChangedを実装する単純なクラスです
<StackPanel> 
    <StackPanel.Resources> 
     <l:MyBool x:Key="MyBool" IsTrue="False" /> 
    </StackPanel.Resources> 
    <CheckBox x:Name="myCheckBox" 
       Content="{Binding RelativeSource={RelativeSource Mode=Self}, Path=IsChecked}" 
       IsChecked="{Binding Source={StaticResource MyBool}, Path=IsTrue, Mode=TwoWay}" 
       HorizontalAlignment="Center" 
       VerticalAlignment="Top"> 
     <CheckBox.Triggers> 
      <EventTrigger RoutedEvent="UIElement.MouseEnter"> 
       <BeginStoryboard x:Name="isCheckedBeginStoryboard"> 
        <Storyboard> 
         <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsChecked"> 
          <DiscreteObjectKeyFrame KeyTime="0"> 
           <DiscreteObjectKeyFrame.Value> 
            <System:Boolean>True</System:Boolean> 
           </DiscreteObjectKeyFrame.Value> 
          </DiscreteObjectKeyFrame> 
         </ObjectAnimationUsingKeyFrames> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger> 
      <EventTrigger RoutedEvent="UIElement.MouseLeave"> 
       <StopStoryboard BeginStoryboardName="isCheckedBeginStoryboard" /> 
      </EventTrigger> 
     </CheckBox.Triggers> 
    </CheckBox> 
    <CheckBox Content="Also two way binding to MyBool.IsTrue no animation" IsChecked="{Binding Source={StaticResource MyBool}, Path=IsTrue}" /> 
    <TextBlock Text="{Binding Source={StaticResource MyBool}, Path=IsTrue, StringFormat={}MyBool.IsTrue: {0}}" /> 
    <TextBlock Text="{Binding ElementName=myCheckBox, Path=IsChecked, StringFormat={}myCheckBox.IsChecked: {0}}" /> 
</StackPanel> 

:あなたがこれを実行しているから見ることができるようにアニメーション、

public class MyBool : INotifyPropertyChanged 
{ 
    private bool _isTrue; 
    public bool IsTrue 
    { 
     get { return _isTrue; } 
     set 
     { 
      if (_isTrue != value) 
      { 
       _isTrue = value; 
       NotifyPropertyChanged("IsTrue"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

あなたのStaticResourceは更新されていません - アニメーションがアクティブでない場合、それはアクティブです。これは、アニメーションが実行されるときにWPFがによって定義されたIsCheckedプロパティの新しい値を提供するためです。これにより、効果的に古い値、つまり双方向のBindingStaticResourceに移動します。アニメーションが終了して停止すると、WPFは古い値IsCheckedを元のバインディング式に戻します。したがって、リソースMyBoolは引き続き更新を受信します。

DependencyProperty値の優先順位に大きな記事がここで見つけることができます:

http://msdn.microsoft.com/en-us/library/ms743230.aspx

は、この情報がお役に立てば幸い!

1

問題はバインドであり、UIでは発生しません。 コードビハインドThisCheckBox.IsChecked = true;でIsCheckedを設定できます。これは、XAMLでバインドしている場合は無視されます。

XAML:

<Window x:Class="WpfApplication3.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> 
    <CheckBox x:Name="ThisCheckBox" IsChecked="{Binding IsTrue}" /> 
</Grid> 

コード:

public partial class Window1 : Window 
{ 
    public Window1() 
    { 
     InitializeComponent(); 

     this.DataContext = new CData(); 

     ThisCheckBox.ClearValue(CheckBox.IsCheckedProperty); 
     //next will work only after clear binding 
     ThisCheckBox.IsChecked = true; 
    } 
} 

public class CData : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private bool _isTrue; 
    public bool IsTrue 
    { 
     get { return _isTrue; } 
     set 
     { 
      if (_isTrue != value) 
      { 
       _isTrue = value; 
       OnPropertyChanged(new PropertyChangedEventArgs("IsTrue")); 
      } 
     } 
    } 

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, e); 
     } 
    } 
} 
関連する問題