おそらくこれを行うより良い方法がありますが、今ここにいるのです。私はいくつかの複雑な型のObservableCollectionにContextMenuをバインドしたいと思います。複合型のプロパティは、メニュー項目に表示されるアイコンを決定します。私がこれを行うことを知っている唯一の方法は、ComplexTypeToMenuItemコンバーターを作成し、それをバインディングに関連付けることでした。ただし、バインダーにコンバーターを追加すると、コレクションが変更されたときにコンテキストメニューが更新されなくなります。コンバーターを削除して、ComplexType.ToString()に依存すると、メニュー項目はうまく更新されます。ただし、この場合アイコンはありません。WPF ContextMenuをObservableCollectionにバインドする際の問題点
これは、簡単に次のように再現することができます。
まず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;
}
}
すべてのヘルプは大歓迎されます!
うん、そうするよ。まあ、私は気が気になりません。テンプレート作成のヒントもありがとう。それはヘッダーのコンテンツには効果的ですが、テンプレート内でアイコンを動的に設定する方法はまだ分かりません。トリガーは、私が既にバインドしているオブジェクトが正しいアイコンパスを持っているため、適切ではないようです。私もスタイルを使用しようとしましたが、メニューの1つのアイテムだけがいつでもアイコンを持っていました。 – EricTheRed
は@EricTheRed:参照[これ](http://stackoverflow.com/questions/7294302/databound-menu-with-icons/7294452#7294452)または[この(http://stackoverflow.com/questions/6177550/ wpf-mvvm-menuitems-styling-issue-with-icons)、これはよくある問題です。 –
パーフェクト!再度、感謝します。 – EricTheRed