2017-03-07 92 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中的状态绑定到窗口的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国家’从字面上,而不是将其分配给Window的DualState属性。有人能够对我在做什么错了一些见解吗?

如果我通过代码或XAML(作为布尔值)在UC上设置状态属性,它工作正常。国家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是窗口的属性。由于错误显示'State'属性没有在'对象'''MainWindow'上找到,因此DataContext是正确的(即,它正在查看窗口)。问题在于它寻找的是'国家'而不是'双重国家' – user7134019

回答

2

DataTrigger的DataContext设置为窗口,这就是为什么它在“状态”窗口中查找的原因。你只需要告诉绑定状态是在用户控件上。试试这个:

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

下面是一个完整的例子:

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

UserControl1.xaml

<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”。 – user7134019

+0

我不是故意暗示问题是数据上下文。你想绑定到用户控件上的State属性,对吗?如果是这样,请尝试答案。 –

+0

我仍然得到相同的错误。我实际上想要绑定窗口的DualState属性。如果我按如下方式放置数据触发器,它可以工作,但我不想对其进行硬编码,而是将属性名称传递给UC。 user7134019

相关问题