2017-03-07 41 views
2

親のプロパティ(別のUCまたはウィンドウでもよい)に基づいてソースを変更したい画像を含む単純なユーザーコントロールがあります。 UCの単純化されたバージョンは、このwpfのユーザーコントロールを親のプロパティにバインドする

<UserControl x:Class="Test.Controls.DualStateButton" ... x:Name="root"> 
    <Grid> 
     <Image Height="{Binding Height, ElementName=root}" Stretch="Fill" Width="{Binding Width, ElementName=root}"> 
      <Image.Style> 
       <Style TargetType="{x:Type Image}"> 
        <Setter Property="Source" Value="{Binding ImageOff, ElementName=root}"/> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding State}" Value="True"> 
          <Setter Property="Source" Value="{Binding ImageOn, ElementName=root}"/> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </Image.Style> 
     </Image> 
    </Grid> 
</UserControl> 

身長のように見える、幅、ImageOff、IMAGEON、そして国家はUC上のすべての依存関係プロパティです。 UCにはDataContextが設定されていないため、親を継承する必要があります。私がしようとしているのは、UCのStateがWindowのDualStateプロパティにバインドされている次のようなものです。

<Window x:Class="Test.MainWindow" DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
... 
    <Grid> 
     <local:DualStateButton State="{Binding DualState}" Height="100" ImageOff="{StaticResource ButtonUp}" ImageOn="{StaticResource ButtonDown}" Width="100"/> 
    </Grid> 
</Window> 

は、私が何を得る、しかし、「国家」プロパティは「オブジェクト」「」メインウィンドウ上で見つからないというエラーは」ので、結合取っているように見える 『文字通りなくUCの状態を』ウィンドウのDualStateプロパティに割り当てます。誰かが私が間違っていることについていくつかの洞察を発することができますか?

UCのStateプロパティをコードまたはXAML(bool値)のどちらかに設定すると、正常に動作します。状態DPは以下のように定義される。

public static readonly DependencyProperty StateProperty = 
    DependencyProperty.Register("State", typeof(bool), typeof(DualStateButton), 
    new PropertyMetadata(false)); 

public bool State 
{ 
    get { return (bool)GetValue(StateProperty); } 
    set { SetValue(StateProperty, value); } 
} 

これが機能するには、データ型がバインディングか何かである必要がありますか?

+1

DualStateプロパティがありますか? DualStateはWindowのプロパティですか?それとも、他のビューモデルの所有物ですか? – loopedcode

+0

FindAncestorを探す – Mafii

+0

はい、DualStateはウィンドウのプロパティです。エラーは 'オブジェクト' '' MainWindow 'に' State 'プロパティが見つからないため、DataContextは正しいです(つまり、ウィンドウを見ています)。問題は、DualStateではなく 'State'を探していることです。 – user7134019

答えて

2

DataTriggerのDataContextがウィンドウに設定されているため、「State」のウィンドウが表示されます。 Stateがユーザコントロール上にあることをバインディングに伝えるだけで済みます。UserControl1.xaml

using System.Windows; 

namespace WpfApplication89 
{ 
    public partial class MainWindow : Window 
    { 
     public static readonly DependencyProperty DualStateProperty = DependencyProperty.Register("DualState", typeof(bool), typeof(MainWindow), new PropertyMetadata(false)); 

     public bool DualState 
     { 
      get { return (bool)GetValue(DualStateProperty); } 
      set { SetValue(DualStateProperty, value); } 
     } 

     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

MainWindow.xaml

<Window x:Class="WpfApplication89.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApplication89" 
     mc:Ignorable="d" 
     DataContext="{Binding RelativeSource={RelativeSource Self}}" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <local:UserControl1 State="{Binding Path=DualState}" /> 
     <CheckBox Content="DualState" IsChecked="{Binding DualState}" /> 
    </StackPanel> 
</Window> 

MainWindow.xaml.cs

:完全な例である。ここ

<DataTrigger Binding="{Binding Path=State, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" Value="True"> 

:これを試してみてください

<UserControl x:Class="WpfApplication89.UserControl1" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WpfApplication89" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Grid> 
     <TextBlock Text="User Control 1"> 
      <TextBlock.Style> 
       <Style TargetType="TextBlock"> 
        <Setter Property="Background" Value="Beige" /> 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding Path=State, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" Value="true"> 
          <Setter Property="Background" Value="Red" /> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </TextBlock.Style> 
     </TextBlock> 
    </Grid> 
</UserControl> 

UserControl1.xaml.cs

using System.Windows; 
using System.Windows.Controls; 

namespace WpfApplication89 
{ 
    public partial class UserControl1 : UserControl 
    { 
     public static readonly DependencyProperty StateProperty = DependencyProperty.Register("State", typeof(bool), typeof(UserControl1), new PropertyMetadata(false)); 

     public bool State 
     { 
      get { return (bool)GetValue(StateProperty); } 
      set { SetValue(StateProperty, value); } 
     } 

     public UserControl1() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

MainWindow.xaml.cs(INotifyPropertyChangedのバージョン)

using System.ComponentModel; 
using System.Runtime.CompilerServices; 
using System.Windows; 

namespace WpfApplication89 
{ 
    public partial class MainWindow : Window, INotifyPropertyChanged 
    { 

     #region INotifyPropertyChanged 
     public event PropertyChangedEventHandler PropertyChanged; 
     protected bool SetProperty<T>(ref T field, T value, [CallerMemberName]string name = null) 
     { 
      if (Equals(field, value)) 
      { 
       return false; 
      } 
      field = value; 
      this.OnPropertyChanged(name); 
      return true; 
     } 
     protected void OnPropertyChanged([CallerMemberName]string name = null) 
     { 
      var handler = this.PropertyChanged; 
      handler?.Invoke(this, new PropertyChangedEventArgs(name)); 
     } 
     #endregion 

     #region Property bool DualState 
     private bool _DualState; 
     public bool DualState { get { return _DualState; } set { SetProperty(ref _DualState, value); } } 
     #endregion 


     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
    } 
} 
+0

問題はデータのコンテキストではありません。ウィンドウを見たいのです。問題は経路です。これは、ステート依存性プロパティの値を 'DualState'にするのではなく、 'State'を文字通り使用しています。 – user7134019

+0

問題がデータ・コンテキストであることを意味するものではありませんでした。あなたは、ユーザーコントロールのStateプロパティにバインドしたい、正しいのですか?もしそうなら、答えを試してください。 –

+0

私はまだ同じエラーが発生します。私は実際には、ウィンドウのDualStateプロパティをバインドします。次のようにデータトリガーを置くと機能しますが、ハードコーディングするのではなく、プロパティ名をUCに渡します。 user7134019

関連する問題