0

こんにちは、

非常に一般的な問題と思われるものがあります。データ コンテキストとしてビュー モデルを持つユーザー コントロールがあります。このユーザー コントロール内の要素は、バインディングの目的でこの 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}

4

3 に答える 3

3

ContextMenus は実際には WPF の VisualTree の一部ではないため、バインディングは期待どおりに機能しません。別の方法として、次のバインディングを試してください。

<MenuItem Header="Spam" Command="{Binding PlacementTarget.DataContext.HideSelectedText,
    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" />
于 2011-03-08T18:28:02.730 に答える