c# - 如何从模板中访问主 DataContext
问题描述
概括
我在数据模板中有一个元素,我想将其绑定到主数据上下文的某些属性。我意识到在这种特定情况下,不同的解决方案可能更可取(我有一个可以避免这种情况的工作解决方案),但我怀疑这种问题可能会再次出现,我想知道在一般情况下如何解决它.
以下是我的具体情况。
细节
数据层次结构:我有一个类型列表A
,每个实例A
都有一个类型列表B
,每个实例B
都有一些其他数据,包括string
文本日志。
UI 结构:我有一个ComboBox
要选择的项目类型A
。我有一个TabControl
代表 type 项目的选项卡B
,取自A
上面的选择。在每个选项卡中,都有一种方法可以输入数据以填充类型的对象B
和一个日志,表示对该实例的更改B
。
支持逻辑SelectionA
:我在每个列表中使用属性(以及SelectionB
在数据上下文中)跟踪所选项目,这些属性MainWindowViewModel
会在它们更改时发出通知。该B
对象还会在其日志文本更改时发出通知。这些确保 UI 响应对支持数据的更改。
问题:我想将通知逻辑全部移动到一个地方(即DataContext
,即MainWindowViewModel
),而不是在B
类中有一些并且需要复制通知逻辑。为此,我添加了一个属性 ( SelectionBLogText
) 来跟踪对象的LogText
属性SelectionB
,并将日志(在模板化选项卡面板中)绑定到主SelectionBLogText
属性。问题是在标签页中,我似乎只能绑定到选定B
对象的属性(从选定的选项卡),而我需要绑定到的属性DataContext
。我尝试过使用RelativeSource
,但到目前为止我没有尝试过任何工作,而且我看文档越多,我就越觉得它是为另一份工作而设计的。
XAML(删除了不相关的细节):
<Window x:Class="WPFQuestion.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFQuestion"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="930">
<DockPanel>
<ComboBox
ItemsSource="{Binding ListOfA}"
SelectedItem="{Binding SelectionA}"
DisplayMemberPath="Name"/>
<TabControl
ItemsSource="{Binding SelectionA}"
SelectedItem="{Binding SelectionB}"
DisplayMemberPath="Name">
<TabControl.ContentTemplate>
<ItemContainerTemplate>
<StackPanel>
<TextBox
IsReadOnly="True"
Text="{Binding Path=???.SelectionBLogText}"/>
<Button Click="ClearLogButton_Click"/>
</StackPanel>
</ItemContainerTemplate>
</TabControl.ContentTemplate>
</TabControl>
</DockPanel>
</Window>
和代码隐藏:
public partial class MainWindow : Window
{
internal MainWindowViewModel vm;
public MainWindow()
{
InitializeComponent();
vm = new MainWindowViewModel();
DataContext = vm;
}
// Various methods for event handling
}
public class A : IEnumerable<B>
{
public string Name { get; set; }
public List<B> Bs { get; set; }
}
public class B // previously : INotifyPropertyChanged
{
public string Name { get; set; }
public string LogText { get; set; }
// various other properties
}
public class MainWindowViewModel : INotifyPropertyChanged
{
private A _a;
private B _b;
public event PropertyChangedEventHandler PropertyChanged;
public List<A> ListOfA { get; set; }
public A SelectionA
{
get => _a;
set
{
if (_a == value)
{
return;
}
_a = value;
RaisePropertyChanged(nameof(SelectionA));
}
}
public B SelectionB
{
get => _b;
set
{
if (_b == value)
{
return;
}
_b = value;
RaisePropertyChanged(nameof(SelectionB));
RaisePropertyChanged(nameof(SelectionBLogText));
}
}
public string SelectionBLogText
{
get => SelectionB.LogText;
set
{
if (SelectionB.LogText == value)
{
return;
}
SelectionB.LogText = value;
RaisePropertyChanged(nameof(SelectionBLogText));
}
}
private void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
解决方案
当您使用相对绑定时,您是否尝试过这样的事情?如果没有,请检查一下。
<TextBox IsReadOnly="True"
Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window},
Path=Datacontext.SelectionBLogText}"/>
推荐阅读
- python - 如何编写一个循环数小时以查找咖啡因吸收的while循环?
- amazon-web-services - AWS Cloudwatch 警报 Terraform
- excel - 计算字段中的 Excel IF 语句
- python - 灰度图像裁剪和转换为 QPixmap
- vb.net - 在公共类库中的多个项目中读取应用程序配置文件条目
- java - 使用 MVP 模式实现 Glide 回调
- java - 初始化列表后出现 NullPointerException
- python - 请求库 - 登录基于 SM 的论坛
- html - Rmarkdown(html):本地搜索目录(toc)
- java - Java从混合数组中删除奇数