質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

7364閲覧

[WPF]UserControlのContextMenuを外部から変更したい

mt-

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2018/12/05 07:41

いつもお世話になります。

前提・実現したいこと

WPFのユーザーコントロール内の一部(ContextMenu)を
ユーザーコントロールの使用元から変更したいのですが、
上記実現する方法が不明なので質問させていただきました。

環境

Visual Studio 2017
C# 4.6.1
WPF
MVVM Lightフレームワーク使用

現状のソースコード

具体的には、下記のようなXamlコードがあり。。。

MainWindow.xaml

xaml

1<Window x:Class="WpfUserControlTest.View.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfUserControlTest.View" 7 mc:Ignorable="d" 8 DataContext="{Binding MainWindow, Source={StaticResource Locator}}" 9 Title="MainWindow" Height="450" Width="800"> 10 <Grid> 11 <Grid.ColumnDefinitions> 12 <ColumnDefinition Width="*" /> 13 <ColumnDefinition Width="*" /> 14 </Grid.ColumnDefinitions> 15 16 <local:CustomListBox Grid.Column="0" Background="AliceBlue" DataContext="{Binding CustomListVM, Source={StaticResource Locator}}" /> 17 <local:CustomListBox Grid.Column="1" Background="Aqua" DataContext="{Binding CustomListVM2, Source={StaticResource Locator}}" /> 18 19 </Grid> 20</Window>

CustomListBox.xaml

xaml

1<UserControl x:Class="WpfUserControlTest.View.CustomListBox" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:WpfUserControlTest.View" 7 mc:Ignorable="d" 8 d:DesignHeight="450" d:DesignWidth="800"> 9 <Grid> 10 11 <ListBox x:Name="_list" 12 Background="{Binding Background, RelativeSource={RelativeSource FindAncestor ,AncestorType={x:Type UserControl}}}" 13 SelectedItem="{Binding SelectedItem}" 14 ItemsSource="{Binding List}" > 15 <ListBox.ItemTemplate> 16 <DataTemplate > 17 <ContentControl> 18 19 <!-- アイテムパネル --> 20 <StackPanel Orientation="Vertical" Background="Transparent" Tag="{Binding Path=DataContext , ElementName=_list}" > 21 <TextBlock Text="{Binding Title}" /> 22 <TextBlock Text="{Binding Data}" /> 23 <StackPanel.ContextMenu> 24 <ContextMenu> 25 <MenuItem Header="削除" 26 CommandParameter="{Binding }" 27 Command="{Binding PlacementTarget.Tag.AssetDeleteCommand , RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" 28 /> 29 </ContextMenu> 30 <!-- 31 <ContextMenu> 32 <MenuItem Header="編集" 33 CommandParameter="{Binding }" 34 Command="{Binding PlacementTarget.Tag.AssetEditCommand , RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" 35 /> 36 </ContextMenu> 37 --> 38 </StackPanel.ContextMenu> 39 </StackPanel> 40 41 </ContentControl> 42 </DataTemplate> 43 </ListBox.ItemTemplate> 44 </ListBox> 45 </Grid> 46</UserControl> 47

上記コードだとListBoxのアイテムを右クリックすると削除項目のみのコンテキストメニューが表示します。

しかしながらこの削除項目が場合によっては編集項目となったり、
「編集」「削除」「開く」が選択できるコンテキストメニューになったりと場合によってコンテキストメニューが変わります

具体的にやりたいコード

最終的にはユーザーコントロールの使用元から下記のように
コンテキストメニューを変更したいです。

MainWindow.xaml

xaml

1<Window x:Class="WpfUserControlTest.View.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfUserControlTest.View" 7 mc:Ignorable="d" 8 DataContext="{Binding MainWindow, Source={StaticResource Locator}}" 9 Title="MainWindow" Height="450" Width="800"> 10 <Grid> 11 <Grid.ColumnDefinitions> 12 <ColumnDefinition Width="*" /> 13 <ColumnDefinition Width="*" /> 14 </Grid.ColumnDefinitions> 15 16 <local:CustomListBox Grid.Column="0" Background="AliceBlue" DataContext="{Binding CustomListVM, Source={StaticResource Locator}}" > 17 <!-- このようにコンテキストメニューを下記のように指定したい --> 18 <ContextMenu> 19 <MenuItem Header="削除" 20 CommandParameter="{Binding }" 21 Command="{Binding PlacementTarget.Tag.AssetDeleteCommand , RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" /> 22 </ContextMenu> 23 </local:CustomListBox> 24 </Grid> 25</Window>

上記のような方法以外でもユーザーコントロール外からユーザーコントロール内部のコンテキストメニューの変更方法等ご存知であればご教示の程よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

メニューにデータをバインドし、メニュー自体を編集するのではなく、データを編集してください。

MenuItemをバインド /WPF

投稿2018/12/05 07:56

Zuishin

総合スコア28673

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mt-

2018/12/05 10:16

ご回答ありがとうございます。 すみませんリンク先の内容を見てみたのですが、 具体的にどのようにすればContextMenuのMenu内容が増やせるのかわかりませんでした。 恐らく「ContextMenu」に対してコレクションをバインドし、 コレクション内の要素のMenuItemとして表示できるという解釈をしたのですが、具体的にどのようにすればよいかリンク先のコードから判断がつきませんでした。。。 実際に下記は試してみましたがうまくいかずといったところです。 [試してみたこと] 上記質問に記載したCustomListBox.xamlのCustomListBoxのコンテキストメニューに対して下記のように設定してみました。 ・ContextMenuのDataContextに  DataContext="{Binding PlacementTarget.Tag.List , RelativeSource={RelativeSource Self}}"  という仮のリストを設定(中身はTitleとDataという文字列型のプロパティをもったインスタンスのコレクションで 内容は{"Title1" , "Data1" } , {"Title2" , "Data2"})が入っています。 これでコンテキストメニューのメニューの表記がListのコレクション内容である2行になるのかと思ったのですが、MenuItemは1つのままでした。 もう少し詳細な方法があればご教示いただけますと幸いです。 ※メニューアイテムのヘッダーは下記のように設定したところ、  無事コレクションの1件目のタイトルである "Title1"が表示できました。  <MenuItem Header="{Binding Title}"
Zuishin

2018/12/05 10:24

サンプルの通り ItemsSource を使わなければなりませんよ。
mt-

2018/12/05 12:00

速いレスポンスで回答していただきありがとうございます。 頂いた情報から下記のようにXamlを設定することで解決できました。 <ContextMenu ItemsSource="{Binding PlacementTarget.Tag.List , RelativeSource={RelativeSource Self}}" x:Name="_Menu" > <ContextMenu.ItemContainerStyle> <Style TargetType="{x:Type MenuItem}"> <Setter Property="Header" Value="{Binding Title}" /> </Style> </ContextMenu.ItemContainerStyle> </ContextMenu> 後は上記対してコマンドやコマンドパラメータを設定していこうと思います。 本当にありがとうございました。
guest

0

最終的にはユーザーコントロールの使用元から下記のように
コンテキストメニューを変更したいです。

CustomListBox.Resourcesにメニューを定義して、DynamicResourceで参照するのはいかがでしょうか。ほぼ同じ使い勝手になると思います。
DynamicResource のマークアップ拡張機能 - WPF .NET Framework | Microsoft Learn

xml:MainWindow.xaml

1<Window 2 x:Class="Q162228.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Q162228" 6 Width="800" 7 Height="450"> 8 <UniformGrid Rows="1"> 9 <local:CustomListBox 10 x:Name="customListBox" 11 Background="AliceBlue" 12 DataContext="{Binding CustomListVM}"> 13 <local:CustomListBox.Resources> 14 <ContextMenu x:Key="contextMenu"> 15 <MenuItem 16 Command="{Binding DataContext.AssetDeleteCommand, Source={x:Reference customListBox}}" 17 CommandParameter="{Binding}" 18 Header="削除" /> 19 </ContextMenu> 20 </local:CustomListBox.Resources> 21 </local:CustomListBox> 22 23 <local:CustomListBox 24 x:Name="customListBox2" 25 Background="Aqua" 26 DataContext="{Binding CustomListVM2}"> 27 <local:CustomListBox.Resources> 28 <ContextMenu x:Key="contextMenu"> 29 <MenuItem 30 Command="{Binding DataContext.AssetEditCommand, Source={x:Reference customListBox2}}" 31 CommandParameter="{Binding}" 32 Header="編集" /> 33 </ContextMenu> 34 </local:CustomListBox.Resources> 35 </local:CustomListBox> 36 </UniformGrid> 37</Window>

xml:CustomListBox.xaml

1<UserControl 2 x:Class="Q162228.CustomListBox" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Margin="8"> 6 <ListBox Background="Transparent" ItemsSource="{Binding List}"> 7 <ListBox.ItemContainerStyle> 8 <Style BasedOn="{StaticResource {x:Type ListBoxItem}}" TargetType="ListBoxItem"> 9 <Setter Property="ContextMenu" Value="{DynamicResource contextMenu}" /> 10 </Style> 11 </ListBox.ItemContainerStyle> 12 <ListBox.ItemTemplate> 13 <DataTemplate> 14 <StackPanel> 15 <TextBlock Text="{Binding Title}" /> 16 <TextBlock Text="{Binding Data}" /> 17 </StackPanel> 18 </DataTemplate> 19 </ListBox.ItemTemplate> 20 </ListBox> 21</UserControl>

cs

1using System.Collections.ObjectModel; 2using System.Windows; 3using CommunityToolkit.Mvvm.ComponentModel; 4using CommunityToolkit.Mvvm.Input; 5 6namespace Q162228; 7 8public partial class MainWindow : Window 9{ 10 public MainWindow() 11 { 12 InitializeComponent(); 13 DataContext = new ViewModel(); 14 } 15} 16 17class ViewModel 18{ 19 public CustomListVM CustomListVM { get; } = new(); 20 public CustomListVM2 CustomListVM2 { get; } = new(); 21} 22partial class CustomListVM 23{ 24 public ObservableCollection<Asset> List { get; } = [new("title1", "data1"), new("title2", "data2"),]; 25 [RelayCommand] private void AssetDelete(Asset asset) => List.Remove(asset); 26} 27partial class CustomListVM2 28{ 29 public ObservableCollection<Asset> List { get; } = [new("title3", "data3"), new("title4", "data4"),]; 30 [RelayCommand] private void AssetEdit(Asset asset) => asset.Data = "edited"; 31} 32partial class Asset(string title, string data) : ObservableObject 33{ 34 public string Title { get; } = title; 35 [ObservableProperty] private string data = data; 36}

NuGet Gallery | CommunityToolkit.Mvvm
MVVM Toolkit の概要 - Community Toolkits for .NET | Microsoft Learn

アプリ動画

投稿2024/11/23 16:28

TN8001

総合スコア10022

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問