【发布时间】:2011-07-11 07:24:49
【问题描述】:
下午好,
我有一个似乎很常见的问题。我有一个用户控件,它有一个视图模型作为它的数据上下文。然后,此用户控件中的元素将此 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 对象。这个工单对象有一个附加的 cmets 集合,它们使用 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}">
我们没有得到任何有用的东西,因为在这种情况下“绑定”等于 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} 没有什么区别?
【问题讨论】:
标签: wpf data-binding findancestor