Menuview中的MenuItem绑定datacontext

时间:2016-11-14 16:06:02

标签: c# wpf listview binding contextmenu

我有ListView DataTemplate,在此模板中有几个文本块和一个按钮。该按钮具有带固定项目的上下文菜单。 listviewitems的绑定工作正常,但将属性绑定到contextmenu似乎不起作用。

<ListView x:Name="lv_clients" Margin="0 22 0 0" SelectionMode="Single">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid Grid.Column="0" Grid.RowSpan="2" Background="{Binding StateColor}">
                </Grid>
                <TextBlock Grid.Column="1" Text="{Binding DisplayString}" Foreground="Black" Height="20" FontWeight="Bold" Padding="2,2,0,0" />
                <Button Click="Button_ListItem_Click" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Top">
                    <Button.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Anrufen" Name="mn_call" Click="mn_call_Click" DataContext={Binding Number} />
                        </ContextMenu>
                    </Button.ContextMenu> ...</Button>
                <StackPanel Grid.Column="1" Grid.Row="1">
                    <TextBlock Text="{Binding State}" Height="20" Padding="2,2,0,0"/>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding FirstEntry.KDKGRS}" Height="20" FontWeight="Bold" Padding="2,2,2,0" HorizontalAlignment="Left" Foreground="{Binding FirstEntry.ConvertedKGFARBE}" />
                        <TextBlock Text="{Binding FirstEntry.ADNAMI}" Height="20" Padding="0,2,0,0" HorizontalAlignment="Left" />
                    </StackPanel>
                </StackPanel>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

为了便于阅读,我删除了一些不必要的代码(样式和列定义)。

重要的部分是MenuItem内的Button。我的基础类有一个公共字符串属性Number。这应该传递给菜单项。但是DataContext的{​​{1}}在click事件中始终为null。

我已经读过一些关于上下文的内容,而不是视觉树的一部分,但我无法绕过它。有人可以用绑定来解释这个问题吗?

编辑基础类的代码: 再次删除了一些不必要的问题代码

MenuItem

ListBox的绑定:

public class PhoneClient
{
    public String Name { get; set; }
    public String Number { get; set; }
    public String Extension { get; set; }
    public String DisplayString
    {
        get
        {
            return String.IsNullOrEmpty(Name) ? Number : String.Format("{0} ({1})", Name, Extension);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

缩小差距

<ContextMenu Tag="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
    <MenuItem Header="Anrufen" Click="mn_call_Click" Name="mn_call" 
              DataContext="{Binding Tag.Number, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
</ContextMenu>

处理程序

private void mn_call_Click(object sender, RoutedEventArgs e)
{
    MenuItem currentMenuItem = (MenuItem)sender;
    string number = (string)currentMenuItem.DataContext;
    // Do Stuff
}

修改

<强> MainWindow.xaml

<Window x:Class="WpfApp.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">
    <Grid Margin="10">
        <ListView x:Name="lv_clients" Margin="0 22 0 0" SelectionMode="Single">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid Background="LightGray" Width="100">
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <Grid Background="LightGreen">
                        </Grid>
                        <TextBlock Text="{Binding DisplayString}" Foreground="Black" Height="20" FontWeight="Bold" Padding="2,2,0,0" />
                        <Button Click="Button_ListItem_Click" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Top">
                            <Button.ContextMenu>
                                <ContextMenu Tag="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
                                    <MenuItem Header="Show" Click="mn_call_Click"  Name="mn_call" DataContext="{Binding Tag.Number, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
                                </ContextMenu>
                            </Button.ContextMenu> ...
                        </Button>
                        <StackPanel Grid.Row="1">
                            <TextBlock Text="{Binding State}" Height="20" Padding="2,2,0,0"/>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="Foo" Height="20" FontWeight="Bold" Padding="2,2,2,0" HorizontalAlignment="Left" Foreground="Blue" />
                                <TextBlock Text="Bar" Height="20" Padding="0,2,0,0" HorizontalAlignment="Left" />
                            </StackPanel>
                        </StackPanel>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Window>

<强> MainWindow.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Collections.Generic;

namespace WpfApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            List<PhoneClient> clients = new List<PhoneClient>();
            clients.Add(new PhoneClient() { Name = "Kumar", Number = "0101010", Extension = "555", State = "New York" });
            clients.Add(new PhoneClient() { Name = "Shanaya", Number = "1010101", Extension = "555", State = "New Jersey" });
            clients.Add(new PhoneClient() { Name = "Billy Bob", Number = "6543210", Extension = "555", State = "Single" });

            lv_clients.ItemsSource = clients;
        }

        public class PhoneClient
        {
            public String Name { get; set; }
            public String Number { get; set; }
            public String Extension { get; set; }
            public String State { get; set; }
            public String DisplayString
            {
                get
                {
                    return String.IsNullOrEmpty(Name) ? Number : String.Format("{0} ({1})", Name, Extension);
                }
            }
        }

        private void mn_call_Click(object sender, RoutedEventArgs e)
        {
            MenuItem currentMenuItem = (MenuItem)sender;
            string number = (string)currentMenuItem.DataContext;
            MessageBox.Show("Number " + number);
        }

        private void Button_ListItem_Click(object sender, RoutedEventArgs e)
        {
            Button currentButton = (Button)sender;
            PhoneClient data = (PhoneClient)currentButton.DataContext;
            MessageBox.Show(data.Name + " tapped");
        }
    }
}