2017-03-07 212 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

相關問題