【问题标题】:Problems binding a WPF ContextMenu to an ObservableCollection with a Converter使用转换器将 WPF ContextMenu 绑定到 ObservableCollection 时出现问题
【发布时间】:2012-01-21 14:27:25
【问题描述】:

也许有更好的方法可以做到这一点,但这就是我现在所处的位置。我想将 ContextMenu 绑定到某个复杂类型的 ObservableCollection。复杂类型的属性将确定菜单项中显示的图标。我知道这样做的唯一方法是创建一个 ComplexTypeToMenuItem 转换器并将其与绑定相关联。但是,一旦我将转换器添加到绑定中,当集合发生更改时,上下文菜单就不再更新。如果我删除转换器并依赖 ComplexType.ToString() 那么菜单项更新就好了。但是,在这种情况下没有图标。

这可以通过以下方式轻松复制:

首先是 XAML

<Window x:Class="GoddamnContextMenuPosition.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:GoddamnContextMenuPosition" 
        Title="MainWindow" Height="350" Width="525">

  <Window.Resources>
    <local:ComplexTypeToMenuItemConverter x:Key="ComplexTypeToMenuItemConverter" />
  </Window.Resources>

    <Grid>
        <TextBox Grid.Row="0" Text="Hooray">
            <TextBox.ContextMenu>
                <ContextMenu ItemsSource="{Binding Objects, Source={x:Static local:Settings.Instance}, Converter={StaticResource ComplexTypeToMenuItemConverter}}">
                </ContextMenu>
            </TextBox.ContextMenu>
        </TextBox>

        <Button Grid.Row="1" Content="Add" Height="25" Width="50" Click="Button_Click"></Button>
    </Grid>
</Window>

现在是代码

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Settings.Instance.Objects.Add(new ComplexType()
        {
            Text = "NEW", Type = 4
        });
    }
}

public class ComplexType
{
    public ComplexType()
    {
        this.TimeStamp = DateTime.Now;
    }

    public string Text
    {
        get;
        set;
    }

    public int Type
    {
        get;
        set;
    }

    public DateTime TimeStamp
    {
        get;
        set;
    }
}

public class ComplexTypeToMenuItemConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var values = value as IEnumerable<ComplexType>;

        if (values == null)
        {
            return new List<MenuItem>
            {
                new MenuItem
                {
                    Header = "Unknown Value"
                }
            };
        }

        IList<MenuItem> items = new List<MenuItem>();

        foreach (ComplexType obj in values)
        {
            BitmapImage bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri("1.png", UriKind.Relative);
            bitmap.EndInit();

            Image image = new Image();
            image.Width = 16;
            image.Source = bitmap;

            MenuItem menuItem = new MenuItem();
            menuItem.Header = string.Format("{0} - {1}", obj.Text, obj.TimeStamp.ToShortTimeString());
            menuItem.Icon = image;

            items.Add(menuItem);
        }

        return items;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class Settings
{
    private static readonly Settings settings = new Settings();

    private Settings()
    {
        this.Objects = new ObservableCollection<ComplexType>
        {
            new ComplexType
            {
                Text = "Item #1",
                Type = 1
            }
        };
    }

    public static Settings Instance
    {
        get
        {
            return settings;
        }
    }

    public ObservableCollection<ComplexType> Objects
    {
        get;
        private set;
    }
}

任何帮助将不胜感激!

【问题讨论】:

    标签: c# wpf xaml data-binding


    【解决方案1】:

    您将ObservableCollection 变成List,它不再提供更新,因此出现了问题。通常,您希望避免在 ItemsSource 绑定中使用转换器。

    不要使用转换器来做这种事情,使用Data Templating

    【讨论】:

    • 是的,就可以了。嗯,我觉得很笨。也感谢您提供有关模板的提示。这对标题内容很有用,但我仍然不确定如何在模板中动态设置图标。触发器似乎不合适,因为我绑定的对象已经具有正确的图标路径。我也尝试过使用一种样式,但在任何时候菜单中只有一个项目有图标。
    • @EricTheRed:见thisthis,这是一个常见问题。
    猜你喜欢
    • 1970-01-01
    • 2012-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多