2015-04-02 59 views
0

在環顧StackOverflow和其他網站後,我可以看到人們在綁定屬性和命令時遇到了很多問題,分別是MenuItemsContextMenus,因爲ContextMenu不是WPF可視化樹的一部分。無論如何,我已經嘗試了幾種不同的解決方案,沒有任何運氣。混淆試圖綁定MenuItem的IsChecked屬性

我有一個MenuItem,它是ContextMenu的一部分。該ContextMenu是綁定到一個ViewModel在其後面的代碼,像這樣一個窗口的一部分:

public partial class Window1 : Window 
{ 
    public MainWindowViewModel ViewModel { get { return DataContext as MainWindowViewModel; } } 

    public Window1() 
    { 
     InitializeComponent(); 

     //There is a property in the App.xaml.cs file that refers to MainWindowViewModel 
     DataContext = App.MainWindowViewModel = new MainWindowViewModel(); 
    } 
} 

,我想綁定到MainWindowViewModel屬性:在

private bool _askBeforeDownloading_Checked = true; 

public bool AskBeforeDownloading_Checked 
{ 
    get { return _askBeforeDownloading_Checked; } 
    set 
    { 
     _askBeforeDownloading_Checked = value; 
     NotifyPropertyChange(() => AskBeforeDownloading_Checked); 
    } 
} 

我當前的嘗試XAML:

<Button Name="Button_1" > 
    <Button.ContextMenu> 
     <ContextMenu x:Name="MainContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" > 
      <MenuItem > 
       <MenuItem IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.AskBeforeDownloading_Checked}" /> 
      </MenuItem> 
     </ContextMenu> 
    </Button.ContextMenu> 
</Button> 

我想到了我的基於this question接受的答案目前XAML,與this guide一起。我錯過了什麼?我沒有收到任何輸出錯誤,但MenuItem沒有得到檢查。有什麼我不是用PlacementTarget

更新:我想指出,我國ContextMenuButton的子控件這將是非常重要的。我已將它添加到我的XAML中。

更新2:我的應用程序中使用探聽之後,我發現我的Button已自動從MainWindowViewModel,因爲它應該繼承。但是,我忽略了可能會影響我的代碼的父母MenuItem。我已經更新了我的XAML,併爲第一次錯過了道歉。

回答

2

DataContext<ContextMenu>繼承,所以你不需要在那裏寫任何特別的東西。

<Button Name="Button_1" > 
    <Button.ContextMenu> 
     <ContextMenu x:Name="MainContextMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" > 
      <MenuItem IsCheckable="True" IsChecked="{Binding AskBeforeDownloading_Checked}" /> 
     </ContextMenu> 
    </Button.ContextMenu> 
</Button> 

爲了更詳細地解釋,該DataContext<ContextMenu>結合是說:

  • 「的RelativeSource自我」 的意思是 「此產品」,這是<ContextMenu>
  • 「PlacementTarget」 的意思是」項目放置在「,在這種情況下是<Button>對象

所以你說的綁定ContextMenu.DataContext財產到Button.DataContext財產。

該屬性應該是您的MainWindowViewModel,因此您可以使用常規綁定綁定到DataContext上的.AskBeforeDownloading_Checked屬性。

或者,你可以刪除.DataContext<ContextMenu>結合,只是保持你的<MenuItem>結合類似於你如何擁有它,但你需要引用Button.DataContext.AskBeforeDownloading_Checked,而不是你現在有Button.AskBeforeDownloading_Checked

<Button Name="Button_1" > 
    <Button.ContextMenu> 
     <ContextMenu x:Name="MainContextMenu> 
      <MenuItem IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AskBeforeDownloading_Checked}" /> 
     </ContextMenu> 
    </Button.ContextMenu> 
</Button> 

的兩種方法,我更喜歡第一個,因爲它允許較少的代碼,如果你要綁定多個項目/屬性的Button.DataContext屬性。

+0

這樣做後不應該檢查我的'MenuItem'嗎?因爲它不是,這導致我相信這裏還有其他事情在發生。 – 2015-04-02 15:27:37

+0

@Ericafterdark MenuItem.IsChecked應該匹配任何'Button.DataContext.AskBeforeDownloading_Checked'。如果它不保持同步,那麼我會再次檢查Button.DataContext是否等於您的MainWindowViewModel。如果您在調試數據綁定時遇到問題,我經常會推薦第三方工具,如[Snoop](https://snoopwpf.codeplex.com/) – Rachel 2015-04-02 15:33:00

+0

我更喜歡您的第一個示例,我同意Snoop會對此有用問題。不過,我認爲可能很重要的一點是,我沒有在XAML中爲我的'Button'設置'DataContext'。這是好的,還是會成爲問題?另外,如果我的'MenuItem'是另一個'MenuItem'的子節點,它也會出現問題嗎? – 2015-04-02 15:36:10

1

您需要添加PlacementTarget.DataContext。請參閱以下代碼。

<Button Name="Button_1" > 
     <Button.ContextMenu> 
      <ContextMenu x:Name="MainContextMenu"> 
       <MenuItem IsCheckable="True" IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.DataContext.AskBeforeDownloading_Checked}" /> 
      </ContextMenu> 
     </Button.ContextMenu> 
    </Button>