回答編集履歴
1
後から見て意図がわからなかったので、わかりやすく書き直し
test
CHANGED
@@ -1,171 +1,113 @@
|
|
1
1
|
WPFのイヤなところなのですが、`ContextMenu`は`VisualTree`が繋がっておらず単純には`FindAncestor`が効きません。
|
2
2
|
|
3
|
-
|
4
|
-
|
5
3
|
* `PlacementTarget`と`Tag`の組み合わせ
|
6
|
-
|
7
4
|
* `BindingProxy`
|
8
|
-
|
9
|
-
|
10
5
|
|
11
6
|
の2つがよくある解決法です。
|
12
7
|
|
8
|
+
```xml
|
9
|
+
<Window
|
10
|
+
x:Class="Questions296143.MainWindow"
|
11
|
+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
12
|
+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
13
|
+
xmlns:local="clr-namespace:Questions296143"
|
14
|
+
Width="800"
|
15
|
+
Height="450">
|
16
|
+
<Window.DataContext>
|
17
|
+
<local:MainVM />
|
18
|
+
</Window.DataContext>
|
19
|
+
<Window.Resources>
|
20
|
+
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
|
21
|
+
</Window.Resources>
|
22
|
+
<Grid>
|
23
|
+
<ListBox ItemsSource="{Binding MyList}">
|
24
|
+
<ListBox.ItemTemplate>
|
25
|
+
<DataTemplate>
|
26
|
+
<UniformGrid Rows="1">
|
13
27
|
|
28
|
+
<GroupBox Header="Original">
|
29
|
+
<Button Content="{Binding DataContext.Fiz, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
|
30
|
+
<Button.ContextMenu>
|
31
|
+
<ContextMenu>
|
32
|
+
<MenuItem Header="{Binding DataContext.Biz, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />
|
33
|
+
</ContextMenu>
|
34
|
+
</Button.ContextMenu>
|
35
|
+
</Button>
|
36
|
+
</GroupBox>
|
14
37
|
|
38
|
+
<!-- Tag xamlのみで済むが、パット見何してるかわかりにくい -->
|
39
|
+
<GroupBox Header="Tag">
|
15
|
-
|
40
|
+
<Button
|
41
|
+
Content="{Binding DataContext.Fiz, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
|
42
|
+
Tag="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
|
43
|
+
<Button.ContextMenu>
|
44
|
+
<ContextMenu>
|
45
|
+
<MenuItem Header="{Binding PlacementTarget.Tag.Biz, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
|
46
|
+
</ContextMenu>
|
47
|
+
|
48
|
+
<!-- あるいは -->
|
49
|
+
<!--<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
|
50
|
+
<MenuItem Header="{Binding Biz}" />
|
51
|
+
</ContextMenu>-->
|
52
|
+
</Button.ContextMenu>
|
53
|
+
</Button>
|
54
|
+
</GroupBox>
|
16
55
|
|
56
|
+
<!-- BindingProxy C#コードが必要だが、xamlはスッキリ -->
|
57
|
+
<GroupBox Header="BindingProxy">
|
58
|
+
<Button Content="{Binding DataContext.Fiz, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
|
59
|
+
<Button.ContextMenu>
|
17
|
-
<
|
60
|
+
<ContextMenu>
|
61
|
+
<MenuItem Header="{Binding Data.Biz, Source={StaticResource proxy}}" />
|
62
|
+
</ContextMenu>
|
63
|
+
</Button.ContextMenu>
|
64
|
+
</Button>
|
65
|
+
</GroupBox>
|
18
66
|
|
19
|
-
x:Class="Questions296143.MainWindow"
|
20
|
-
|
21
|
-
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
22
|
-
|
23
|
-
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
24
|
-
|
25
|
-
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
26
|
-
|
27
|
-
xmlns:local="clr-namespace:Questions296143"
|
28
|
-
|
29
|
-
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
30
|
-
|
31
|
-
Title="MainWindow"
|
32
|
-
|
33
|
-
Width="800"
|
34
|
-
|
35
|
-
Height="450"
|
36
|
-
|
37
|
-
mc:Ignorable="d">
|
38
|
-
|
39
|
-
<Window.DataContext>
|
40
|
-
|
41
|
-
<local:MainVM />
|
42
|
-
|
43
|
-
</Window.DataContext>
|
44
|
-
|
45
|
-
<Window.Resources>
|
46
|
-
|
47
|
-
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
|
48
|
-
|
49
|
-
</Window.Resources>
|
50
|
-
|
51
|
-
<
|
67
|
+
<!-- AncestorLevelとかの話ではない。ツリーが繋がってないので出るわけがない! -->
|
52
|
-
|
53
|
-
<ListBox.ItemTemplate>
|
54
|
-
|
55
|
-
<DataTemplate>
|
56
|
-
|
57
|
-
<StackPanel>
|
58
|
-
|
59
|
-
<B
|
68
|
+
<GroupBox Header="takapi__cs">
|
60
|
-
|
69
|
+
<Button Content="{Binding DataContext.Fiz, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
|
61
|
-
<Button.ContextMenu>
|
70
|
+
<Button.ContextMenu>
|
62
|
-
|
63
|
-
<ContextMenu>
|
71
|
+
<ContextMenu>
|
64
|
-
|
65
|
-
<MenuItem Header="{Binding
|
72
|
+
<MenuItem Header="{Binding DataContext.Biz, RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType=Window}}" />
|
66
|
-
|
67
|
-
</ContextMenu>
|
73
|
+
</ContextMenu>
|
68
|
-
|
69
|
-
</Button.ContextMenu>
|
74
|
+
</Button.ContextMenu>
|
70
|
-
|
71
|
-
</Button>
|
75
|
+
</Button>
|
72
|
-
|
73
|
-
<Button Content="Tag" Tag="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
|
74
|
-
|
75
|
-
<Button.ContextMenu>
|
76
|
-
|
77
|
-
<ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
|
78
|
-
|
79
|
-
<MenuItem Header="{Binding Path=Biz}" />
|
80
|
-
|
81
|
-
</ContextMenu>
|
82
|
-
|
83
|
-
</Button.ContextMenu>
|
84
|
-
|
85
|
-
</B
|
76
|
+
</GroupBox>
|
86
|
-
|
87
|
-
<Button Content="BindingProxy">
|
88
|
-
|
89
|
-
<Button.ContextMenu>
|
90
|
-
|
91
|
-
<ContextMenu>
|
92
|
-
|
93
|
-
<MenuItem Header="{Binding Path=Data.Biz, Source={StaticResource proxy}}" />
|
94
|
-
|
95
|
-
|
77
|
+
</UniformGrid>
|
96
|
-
|
97
|
-
</Button.ContextMenu>
|
98
|
-
|
99
|
-
</Button>
|
100
|
-
|
101
|
-
</StackPanel>
|
102
|
-
|
103
|
-
</DataTemplate>
|
78
|
+
</DataTemplate>
|
104
|
-
|
105
|
-
</ListBox.ItemTemplate>
|
79
|
+
</ListBox.ItemTemplate>
|
106
|
-
|
107
|
-
</ListBox>
|
80
|
+
</ListBox>
|
108
|
-
|
81
|
+
</Grid>
|
109
82
|
</Window>
|
110
|
-
|
111
83
|
```
|
112
84
|
|
113
|
-
|
114
|
-
|
115
|
-
```
|
85
|
+
```cs
|
116
|
-
|
117
86
|
using System.Collections.Generic;
|
118
|
-
|
119
87
|
using System.Windows;
|
120
88
|
|
121
|
-
|
122
|
-
|
123
89
|
namespace Questions296143
|
124
|
-
|
125
90
|
{
|
126
|
-
|
127
91
|
class BindingProxy : Freezable
|
128
|
-
|
129
92
|
{
|
130
|
-
|
131
93
|
public object Data { get => GetValue(DataProperty); set => SetValue(DataProperty, value); }
|
132
|
-
|
133
94
|
public static readonly DependencyProperty DataProperty
|
134
|
-
|
135
95
|
= DependencyProperty.Register(nameof(Data), typeof(object), typeof(BindingProxy),
|
136
|
-
|
137
96
|
new PropertyMetadata(null));
|
138
97
|
|
139
|
-
|
140
|
-
|
141
98
|
protected override Freezable CreateInstanceCore() => new BindingProxy();
|
142
|
-
|
143
99
|
}
|
144
100
|
|
145
|
-
|
146
|
-
|
147
101
|
class MainVM
|
148
|
-
|
149
102
|
{
|
150
|
-
|
151
103
|
public string Biz { get; } = "Biz";
|
152
|
-
|
153
104
|
public string Fiz { get; } = "Fiz";
|
154
|
-
|
155
105
|
public List<string> MyList { get; } = new List<string> { "hoge" };
|
156
|
-
|
157
106
|
}
|
158
107
|
|
159
|
-
|
160
|
-
|
161
108
|
public partial class MainWindow : Window
|
162
|
-
|
163
109
|
{
|
164
|
-
|
165
110
|
public MainWindow() => InitializeComponent();
|
166
|
-
|
167
111
|
}
|
168
|
-
|
169
112
|
}
|
170
|
-
|
171
113
|
```
|