2011-04-25 101 views
4

我想知道如何將MenuItem.Header綁定到父窗口/用戶控件依賴項屬性?下面是一個簡單的例子:如何將MenuItem.Header綁定到Window/UserControl依賴項屬性?

Window1.xaml

<Window x:Class="WpfApplication1.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" x:Name="self"> 
    <Grid> 
     <Grid.ContextMenu> 
      <ContextMenu> 
       <MenuItem Header="{Binding Path=MenuText, ElementName=self}" /> 
      </ContextMenu> 
     </Grid.ContextMenu> 
     <TextBlock Text="{Binding Path=MenuText, ElementName=self}"/> 
    </Grid> 
</Window> 

Window1.xaml.cs

public partial class Window1 : Window { 
    public static readonly DependencyProperty MenuTextProperty = DependencyProperty.Register(
     "MenuText", typeof (string), typeof (Window1), new PropertyMetadata("Item 1")); 

    public Window1() 
    { 
     InitializeComponent(); 
    } 

    public string MenuText { 
     get { return (string)this.GetValue(MenuTextProperty); } 
     set { this.SetValue(MenuTextProperty, value); } 
    } 
} 

在我的情況下,文本塊顯示 「項目1」,並上下文菜單顯示空的項目。我在做什麼錯了?在我看來,我面臨着嚴重誤導WPF數據綁定原則的問題。

回答

7

你應該在Visual Studio中的輸出窗口看到:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=self'. BindingExpression:Path=MenuText; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Header' (type 'Object')

這是因爲文本菜單從斷開的VisualTree,你需要以不同的方式做到這一點約束力。

一種方式是通過ContextMenu.PlacementTarget(這應該是網格),你可以使用它的DataContext建立一個綁定,如:

<MenuItem Header="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.MenuText}"/> 

或設置的DataContext在文本菜單本身:

<ContextMenu DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.DataContext}"> 
    <MenuItem Header="{Binding Path=MenuText}"/> 
</ContextMenu> 

如果這不是一個選項(因爲Grid的DataContext不能是Window/UserControl),您可以嘗試通過Grid的Tag將引用傳遞給Window/UserControl。

<Grid ... 
     Tag="{x:Reference self}"> 
    <Grid.ContextMenu> 
     <!-- The DataContext is now bound to PlacementTarget.Tag --> 
     <ContextMenu DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.Tag}"> 
      <MenuItem Header="{Binding Path=MenuText}"/> 
     </ContextMenu> 
    ... 

作爲一個側面說明:因爲這種行爲我傾向於在App.xaml定義一個幫手風格,使所有ContextMenus「僞繼承」在DataContext從他們的父母:

<!-- Context Menu Helper --> 
    <Style TargetType="{x:Type ContextMenu}"> 
     <Setter Property="DataContext" Value="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}"/> 
    </Style> 
+0

請您澄清如何通過標記將引用傳遞給Window/UserControl?如果我使用Tag =「{x:Reference self}」語法,則會出現編譯錯誤**「標記'引用'在XML命名空間中不存在'http://schemas.microsoft.com/winfx/2006/xaml' 。**我使用VS2008和.NET框架3.5。 – 2011-04-26 06:04:53

+0

只存在於.NET 4中,您應該可以使用Binding代替,如'Tag =「{Binding ElementName = self}」' – 2011-04-26 10:58:47

+0

Clear.Thanks很多 – 2011-04-26 13:14:54

相關問題