2017-03-07 1 views
2

부모 (다른 UC 또는 Window 일 수 있음)의 속성을 기반으로 소스를 변경하려는 이미지가 포함 된 간단한 사용자 정의 컨트롤이 있습니다. 이터 : 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, 이미지 온, 그리고 국가는 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> 

내가 무엇을 얻을 그러나, '국가'속성은 '객체' ''MainWindow를 찾을 수 없습니다한다는 오류입니다 ', 그래서 바인딩 복용 보인다'문자 그대로가 아니라 UC의 상태 ' 윈도우의 DualState 속성에 할당합니다. 누군가 내가 잘못하고있는 것에 대해 통찰력을 줄 수 있습니까?

UC에서 상태 속성을 코드 또는 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는 window 속성입니다. 오류는 'State'속성이 'object' ''MainWindow '에 없기 때문에 DataContext가 정확합니다 (예 : 창을보고있는 것). 문제는 그것이 'DualState'가 아닌 'State'를 찾고 있다는 것입니다. – user7134019

답변

2

DataTrigger의 DataContext가 창에 설정되어 있기 때문에 "상태"창이 보입니다. State가 사용자 정의 컨트롤에 있다는 것을 바인딩에 알리기 만하면됩니다. 이 시도 :,369 UserControl1.xaml

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를

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(); 
     } 
    } 
} 

: 여기


<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

문제는 데이터 컨텍스트가 아니므로 창을보고 싶습니다. 문제는 경로입니다. 그것은 'State'를 문자 그대로 'DualState'가 될 상태 종속성 속성을 사용하는 대신 사용합니다. – user7134019

+0

문제가 데이터 컨텍스트라는 것을 의미하지는 않습니다. 사용자 정의 컨트롤의 State 속성에 바인딩하고 싶습니까? 그렇다면 대답을 시도하십시오. –

+0

여전히 같은 오류가 발생합니다. 사실 윈도우의 DualState 속성을 바인딩하고 싶습니다.다음과 같이 데이터 트리거를 넣으면 작동하지만 하드 코드를 사용하지 않고 UC에 속성 이름을 전달합니다. user7134019

관련 문제