我有一个带有一些文本框的用户控件(名为mUserControl),其内容受限于类(模型)的属性,名为Module。用户控件本身具有一个Module类型的自定义依赖属性(ItemSource)。所以我可以将文本框的内容绑定到Module的属性。
此用户控件是更大视图(HomeScreenView)的一部分。我可以从HomeScreenViewmodel轻松访问ItemsSource。一切正常,除了文本框上的ContextMenu。我收到了绑定错误。 ContextMenu没有看到用户控件的ItemsSource属性,而所有其他元素都这样做。我知道,ContextMenu在不同的可视化树上。我尝试过不同的方法来完成这项工作,却没有成功。欢迎任何建议!
UserControl xaml(为简洁起见而简化):
<UserControl x:Class="xxx.Views.ModuleFrameView"
x:Name="mUserControl">
<Grid>
<TextBox x:Name="txt5" Text="{Binding ItemSource.Ch1SET,
ElementName=mUserControl}" IsEnabled="{Binding ItemSource.IsEnbl_5,
ElementName=mUserControl}" IsReadOnly="True"
TextAlignment="Center" ContextMenuService.ShowOnDisabled="True"
Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
<TextBox.ContextMenu >
<ContextMenu Name="cm">
<MenuItem Header="Enable" cal:Message.Attach="cmEnable($source)" IsCheckable="True" IsChecked="
{Binding Path=PlacementTarget.Tag.DataContext.ItemSource.IsEnbl_5,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TextBox}}"/>
</ContextMenu>
</TextBox.ContextMenu>
<!--...-->
ModuleFrameView在代码隐藏文件中定义了ItemSource属性:
public Module ItemSource
{
get { return (Module)GetValue(ItemSourceProperty); }
set { SetValue(ItemSourceProperty, value); }
}
public static readonly DependencyProperty ItemSourceProperty =
DependencyProperty.Register("ItemSource", typeof(Module), typeof(ModuleFrameView), new PropertyMetadata(default(Module)));
此类型的DP模块:
public class Module : PropertyChangedBase
{
private string _ch1SET;
public string Ch1SET
{
get { return _ch1SET; }
set
{
if (_ch1SET == value) return;
_ch1SET = value;
NotifyOfPropertyChange(() => Ch1SET);
}
}
private bool _isEnbl_5;
public bool IsEnbl_5
{
get { return _isEnbl_5; }
set
{
if (_isEnbl_5 == value) return;
_isEnbl_5 = value;
NotifyOfPropertyChange(() => IsEnbl_5);
}
}
//...
//...lot of properties
第二个用户控件(上面提到的更大的视图)&#39; xaml:
<UserControl x:Class="xxx.Views.HomeScreenView">
<Grid>
<ContentControl>
<loc:ModuleFrameView Grid.Row="0" Grid.Column="0" ItemSource="{Binding ModuleArr[0]}"/>
<loc:ModuleFrameView Grid.Row="0" Grid.Column="1" ItemSource="{Binding ModuleArr[1]}"/>
<!--...-->
答案 0 :(得分:0)
有点拿铁但是如果你的datacontext设置正确,你不需要名字,你可以简化如下(未经测试)但DP可以直接访问+“ItemSource”是错误的属性名称,如果你只有一个元素=&GT;改为“CurrentModule”
<UserControl x:Class="xxx.Views.ModuleFrameView">
<Grid x:Name="ROOT">
<TextBox Text="{Binding CurrentModule.Ch1SET}" IsEnabled="{Binding CurrentModule.IsEnbl_5}" IsReadOnly="True"
TextAlignment="Center" ContextMenuService.ShowOnDisabled="True">
<TextBox.ContextMenu >
<ContextMenu>
<MenuItem Header="Enable" cal:Message.Attach="cmEnable($source)" IsCheckable="True" IsChecked="{Binding Path=CurrentModule.IsEnbl_5, ElementName="ROOT"}"/>
</ContextMenu>
</TextBox.ContextMenu>
除此之外,您的HomeScreenView需要被绑定到模块集合的列表替换,并为您的loc定义项目模板:ModuleFrameView with“List ItemSource =”{Binding ModuleArr}“
答案 1 :(得分:0)
PlacementTarget
是父ContextMenu
的属性,因此您应使用ContextMenu
作为AncestorType
而不是TextBox
:
<MenuItem Header="Enable" cal:Message.Attach="cmEnable($source)" IsCheckable="True"
IsChecked="{Binding Path=PlacementTarget.Tag.DataContext.ItemSource.IsEnbl_5,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/>