2017-03-02 163 views
1

是否可以將ListBox ContextMenu的CommandParameter綁定到ListBox的Selected Item?我應該說ContCommand是在主窗口中,當點擊上下文菜單項時調用 - 但是,我需要讓參數正常工作。WPF:將ListBox ContextMenu的命令參數綁定到ListBox的選定項目

我試過,但綁定失敗:

<Window x:Class="ListBoxContextMenu.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:ListBoxContextMenu" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 

    <Grid> 
     <StackPanel> 
      <TextBlock Text="ListBox here:"/> 
      <ListBox ItemsSource="{Binding Items}" MinHeight="100" TabIndex="0" x:Name="LB"> 
       <ListBox.ContextMenu> 
        <ContextMenu> 
         <MenuItem Header="Foo" Command="{Binding ContCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}},Path=SelectedItem}"/> 
        </ContextMenu> 
       </ListBox.ContextMenu> 
      </ListBox> 
     </StackPanel> 
    </Grid> 
</Window> 

C#代碼主窗口:

using System.Collections.ObjectModel; 
using System.Windows; 
using System.Windows.Input; 
using MvvmFoundation.Wpf; 

    namespace ListBoxContextMenu 
    { 
     public partial class MainWindow : Window 
     { 
      public MainWindow() 
      { 
       InitializeComponent(); 
       DataContext = this; 
       Loaded += (sender, e) => MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); 
       ContCommand = new RelayCommand<object>((object o) => 
       { 
        System.Diagnostics.Debug.WriteLine("Context Menu pressed"); 
       }); 
      } 

      public ObservableCollection<string> Items { get; set; } = new ObservableCollection<string>{"Fred", "Jim", "Sheila"}; 
      public RelayCommand<object> ContCommand { get; set; } 
     } 
    } 
+0

刪除代碼樣本的非相關項目。比如'using' /'NameSpace'和Window屬性。只關注閱讀它的人的不可或缺的部分。 – OmegaMan

回答

2

ListBox不是ContextMenu的視覺祖先,因爲後者駐留在自己的視覺樹。

但是你可以綁定到ContextMenuPlacementTarget,這是ListBox

這工作:

<ListBox ItemsSource="{Binding Items}" MinHeight="100" TabIndex="0" x:Name="LB"> 
    <ListBox.ContextMenu> 
     <ContextMenu> 
      <MenuItem Header="Foo" Command="{Binding ContCommand}" 
           CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, 
           Path=PlacementTarget.SelectedItem}"/> 
     </ContextMenu> 
    </ListBox.ContextMenu> 
</ListBox> 
0

上下文菜單在不同的樹,所以結合是棘手視情況而定。這裏有兩個選項:

綁定到通過其名稱列表框如

Binding SelectedItem, ElementName=LB 

使用參考名稱

有時元素名稱綁定失敗和一個具有至使用x:ref名稱(你有)

Binding Source={x:Reference LB}, Path=SelectedItem 

至於爲什麼,引用x:Reference

In WPF and XAML 2006, element references are addressed by the framework-level feature of ElementName binding. For most WPF applications and scenarios, ElementName binding should still be used. Exceptions to this general guidance might include cases where there are data context or other scoping considerations that make data binding impractical and where markup compilation is not involved.

+0

''產生綁定錯誤:System.Windows.Data Error:4:Can not find source for綁定參考'ElementName = LB'。 BindingExpression:路徑=的SelectedItem;的DataItem = NULL;目標元素是'MenuItem'(Name ='');目標屬性是'CommandParameter'(類型'對象') –

+0

@AdrianS你是否嘗試過x:reference綁定呢? – OmegaMan

+0

x:引用綁定導致引發異常:System.Windows.Markup.XamlParseException:'由於循環依賴性,無法調用MarkupExtension.ProvideValue。 MarkupExtension內部的屬性不能引用引用MarkupExtension結果的對象。受影響的MarkupExtensions爲: 'System.Windows.Data.Binding'行號'18'和行位置'80'。' –

0

添加Mode=FindAncestorRelativeSource結合。

CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Path=SelectedItem}" 
+0

我得到「System.Windows.Data錯誤:4:無法找到與參考綁定的源'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.ListBox',AncestorLevel ='1''。BindingExpression:路徑=的SelectedItem;的DataItem = NULL;目標元素是'MenuItem'(Name ='');目標屬性是'CommandParameter'(類型'對象')「 –

相關問題