こんにちは、
非常に一般的な問題と思われるものがあります。データ コンテキストとしてビュー モデルを持つユーザー コントロールがあります。このユーザー コントロール内の要素は、バインディングの目的でこの ViewModel を使用します。
ビューモデル
public class TicketDetailsViewModel : ViewModelBase
{
public DelegateCommand<object> HideSelectedText { get; private set; }
private Ticket _ticket;
public Ticket Ticket
{
get { return _ticket; }
set
{
_ticket = value;
this.RaisePropertyChanged(p => p.Ticket);
}
}
}
私の ViewModel には、単一の Ticket オブジェクトが含まれています。このチケット オブジェクトにはコメントのコレクションが添付されており、これらは ItemsControl を使用してチケット表示ユーザー コントロールにレンダリングされます。
<ItemsControl ItemsSource="{Binding Path=Ticket.Comments}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border CornerRadius="15" Background="{Binding Path=CommentType, ConverterParameter=CommentType, Converter={StaticResource ResourceKey=commentColorConverter}}" Padding="10" Margin="40,10,40,0">
<TextBox x:Name="tbComment" Text="{Binding CommentText}" IsReadOnly="True">
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Spam" Command="{Binding Path=DataContext.HideSelectedText,RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type UserControl} }}">
</MenuItem>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
この ItemsControl によってレンダリングされる各 TextBox には、ContextMenu がアタッチされていることがわかります。私がやろうとしているのは、この ContextMenuItem のコマンドを ViewModel の DelegateCommand にバインドすることです。もちろん、単純に使用します。
<MenuItem Header="Spam" Command="{Binding HideSelectedText}">
このコンテキストでの「Binding」は Ticket.Comment と等しいため、有用なものは何も得られないため、HideSelectedText が実際に何であるかはわかりません。
これに似た質問がたくさんあるようで、すべての回答が RelativeSource ソリューションに向けられているようです。元の XAML コードでわかるように、これと他の多くのバージョンを試しました (AncestorLevel を設定した場合と設定しない場合、AncestorType={x:Type ItemsControl}、AncestorType={x:Type Window}、AncestorType= を使用) {x:Type DataTemplate} ect) および ALL は、次のような出力エラーを生成します。
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=DataContext.HideSelectedText; DataItem=null; target element is 'MenuItem' (Name=''); target property is 'Command' (type 'ICommand')
また
System.Windows.Data Error: 40 : BindingExpression path error: 'HideSelectedText' property not found on 'object' ''TicketComment' (HashCode=49290260)'. BindingExpression:Path=DataContext.HideSelectedText; DataItem='ContextMenu' (Name=''); target element is 'MenuItem' (Name=''); target property is 'Command' (type 'ICommand')
では、なぜこの解決策は非常に多くの人に効果があるように見えますが、私にとっては、単純に入力するのと何の違いもありません{Binding HideSelectedText}
。