1

我正在尝试获取 ContextMenu 的 SelectedItem。

XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <StackPanel>
        <ListBox x:Name="MyListBox" ItemsSource="{Binding MyList}" SelectedItem="{Binding MySelectedItem}">
            <ListBox.ContextMenu>
                <ContextMenu ItemsSource="{Binding OCContext}" PreviewMouseDown="ContextMenu_PreviewMouseDown"/>
            </ListBox.ContextMenu>
        </ListBox>
        <Button Content="Delete Item" Click="Button_Click"/>
        </StackPanel>
    </Grid>
</Window>

代码背后

public partial class MainWindow : Window
{
    public MainWindow()
    {
        OCContext = new ObservableCollection<string>();
        MyList = new ObservableCollection<string>();
        MyList.Add("Item 1");
        MyList.Add("Item 2");
        InitializeComponent();
    }

    public ObservableCollection<string> MyList { get; set; }
    public ObservableCollection<string> OCContext { get; set; }
    public string MySelectedItem { get; set; }

    private void ContextMenu_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        MenuBase s = sender as MenuBase;
        ItemCollection ic = s.Items;
        string MyItem = "";
        MyItem = (string)ic.CurrentItem;
        MyList.Add(MyItem);
        OCContext.Remove(MyItem);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (MySelectedItem != null)
        {
            OCContext.Add(MySelectedItem);
            MyList.Remove(MySelectedItem);
        }
    }
}

您可以复制/粘贴代码,程序应该可以工作。

该程序正在执行以下操作:

您可以在 ListBox 中选择一个项目。如果单击“删除项目”,该项目将被删除并添加到 ContextMenu。如果单击 ContextMenu-Item,则该项目应再次添加到 ListBox 并从 ContextMenu 中删除。你应该能够一遍又一遍地这样做......

所以 ContextMenu 被绑定到一个集合。我用ic.CurrentItem. 问题是,当我删除 ListBox 中的项目并再次添加时(通过单击 ContextMenu 上的项目),ic.CurrentItem 将为空。

为什么?

编辑: Cyphryx 的解决方案正在工作,但现在我正在尝试通过使用 MVVM/Binding 来做同样的事情:

XAML:

<ContextMenu x:Name="MyContext" ContextMenu="{Binding MyContextMenu}" ItemsSource="{Binding OCContext}"/>

视图模型:

    private ObservableCollection<string> _occontext;
    public ObservableCollection<string> OCContext
    {
        get
        {
            if (_occontext == null)
                _occontext = new ObservableCollection<string>();
            MyContextMenu.Items.Clear();
            foreach (var str in _occontext)
            {
                var item = new System.Windows.Controls.MenuItem();
                item.Header = str;
                item.Click += Content_MouseLeftButtonUp;
                MyContextMenu.Items.Add(item);
            }

            return _occontext;
        }
        set
        {
            _occontext = value;
            RaisePropertyChanged(() => OCContext);
        }
    }

    private void Content_MouseLeftButtonUp(object sender, RoutedEventArgs e)
    {
        var s = sender as System.Windows.Controls.MenuItem;
        if (s == null) return;
        string ic = s.Header.ToString();
    }

    private System.Windows.Controls.ContextMenu _mycontextmenu;
    public System.Windows.Controls.ContextMenu MyContextMenu
    {
        get
        {
            if (_mycontextmenu == null)
                _mycontextmenu = new System.Windows.Controls.ContextMenu();
            return _mycontextmenu;
        }
        set
        {
            _mycontextmenu = value;
            RaisePropertyChanged(() => MyContextMenu);
        }
    }

Content_MouseLeftButtonUp是不是被叫了?...

4

1 回答 1

1

Rudi,据我所知,您不能将事件处理程序分配给绑定源中的单个对象。您只能将 WPF 事件处理程序用于它所绑定的对象,因此,您必须手动填充上下文菜单,从而允许您在那时添加事件处理程序。简而言之,当您添加 PreviewMouseDown="ContextMenu_PreviewMouseDown"到 WPF 时,处理程序被分配给上下文菜单,但是当绑定添加单个菜单项时,它不会将该处理程序添加到每个项目,让您的事件句柄 ;-) 下面是代码将解决此问题:

WPF

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <StackPanel>
            <ListBox x:Name="MyListBox" ItemsSource="{Binding MyList}" SelectedItem="{Binding MySelectedItem}" Height="Auto" MinHeight="20">
                <ListBox.ContextMenu>
                    <ContextMenu Name="ContextMenu" Opened="ContextMenu_Opened" />
                </ListBox.ContextMenu>
            </ListBox>
            <Button Content="Delete Item" Click="Button_Click"/>
        </StackPanel>
    </Grid>
</Window>

代码背后:

public MainWindow()
{
    OCContext = new ObservableCollection<string>();
    MyList = new ObservableCollection<string>();
    MyList.Add("Item 1");
    MyList.Add("Item 2");
    InitializeComponent();

}
public ObservableCollection<string> MyList { get; set; }
public ObservableCollection<string> OCContext { get; set; }
public string MySelectedItem { get; set; }

private void ContextMenu_Opened(object sender, EventArgs e)
{
    ContextMenu.Items.Clear();
    foreach (var str in OCContext)
    {
        var item = new MenuItem();
        item.Header = str;
        item.Click += Content_MouseLeftButtonUp;
        ContextMenu.Items.Add(item);
    }
}

private void Content_MouseLeftButtonUp(object sender, EventArgs e)
{
    var s = sender as MenuItem;
    if (s == null) return;
    var ic = s.Header.ToString();

    MyList.Add(ic);
    OCContext.Remove(ic);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (MySelectedItem != null)
    {
        OCContext.Add(MySelectedItem);
        MyList.Remove(MySelectedItem);
    }
}

我希望这有帮助。

Cyphryx

于 2013-07-11T15:46:27.120 回答