C# 当应用的DataTemplate没有资源密钥时,如何获取其内部的根元素?
我希望在应用的C# 当应用的DataTemplate没有资源密钥时,如何获取其内部的根元素?,c#,wpf,mvvm,datatemplate,xaml-resources,C#,Wpf,Mvvm,Datatemplate,Xaml Resources,我希望在应用的DataTemplate中获取根元素。我尝试过,但它对我不起作用,因为对于由MyItemsControl.ItemContainerGenerator.ContainerFromItem(vm)返回的ContentPresenter,其中vm是一个视图模型,ContentPresenter.ContentTemplate是null,尽管ContentPresenter.Content是相应的数据(相同的视图模型) 我会像访问资源一样访问DataTemplates,但我不能提供Dat
DataTemplate
中获取根元素。我尝试过,但它对我不起作用,因为对于由MyItemsControl.ItemContainerGenerator.ContainerFromItem(vm)
返回的ContentPresenter
,其中vm
是一个视图模型,ContentPresenter.ContentTemplate
是null
,尽管ContentPresenter.Content
是相应的数据(相同的视图模型)
我会像访问资源一样访问DataTemplate
s,但我不能提供DataTemplate
s资源键,因为我希望它们自动应用于ItemsControl
中的所有项目。因此,我必须找到一种方法,从ItemsControl
中的项目获取DataTemplate
我可以使用if
-else
来确定vm.GetType()函数中的DataTemplate
资源,但是我想在没有ItemContainerGenerator
的情况下,根据MVVM模式实现我的愿望,如果可能的话,也不需要硬编码类型
下面是我认为与代码相关的内容。例如,我使用MyAudioFileSelector
frommain window
将一些设置从数据文件加载到UI中,我不确定MVVM是如何做到这一点的
C#来自我的实际项目
(我假设目前只有一个AudioFileSelector和一个ImageFileSelector,但将来可能会有更多。)
内部控制GetRootControlFromContentPresenter(ContentPresenter容器)
{
//在这里放什么?
返回null;
}
内部音频文件选择器MyAudioFileSelector
{
得到
{
foreach(在MyItemsControl.ItemsSource中设置DataVM)
{
如果(vm是AudioFileSettingDataVM)
{
返回(AudioFileSelector)GetRootControlFromContentPresenter(
(ContentPresenter)MyItemsControl.ItemContainerGenerator.ContainerFromItem(vm));
}
}
返回null;
}
}
内部ImageFileSelector MyImageFileSelector
{
得到
{
foreach(在MyItemsControl.ItemsSource中设置DataVM)
{
如果(vm是ImageFileSettingDataVM)
{
返回(ImageFileSelector)GetRootControlFromContentPresenter(
(ContentPresenter)MyItemsControl.ItemContainerGenerator.ContainerFromItem(vm));
}
}
返回null;
}
}
测试示例
XAML
视图模型1
视图模型2
C#代码隐藏
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
已加载私有void MyItemsControl_(对象发送方,RoutedEventTarget e)
{
var oc=新的ObservableCollection();
oc.Add(新的ViewModel1());
oc.Add(新的ViewModel2());
MyItemsControl.ItemsSource=oc;
Dispatcher.BeginInvoke(新操作(()=>
{
var container=(ContentPresenter)MyItemsControl.ItemContainerGenerator.ContainerFromItem(oc[0]);
//此处container.ContentTemplate为空
Debugger.Break();
}),System.Windows.Threading.DispatcherPriority.Loaded);
}
}
公共类ViewModelBase
{
}
公共类ViewModel1:ViewModelBase
{
}
公共类ViewModel2:ViewModelBase
{
}
我的另一个相关问题是
多谢各位
更新1
在我的实际程序中,我有更复杂的DataTemplate
s。TextBlock
只是一个例子
我需要一个ContentTemplate
来查找特定容器/项目/索引所使用的DataTemplate
。我使用多个DataTemplate
来根据它们的数据类型自动应用
更新2
我需要DataTemplate
在应用程序的设置窗口中显示ItemsControl
中的不同控件,每个控件都将DataContext
设置为每个设置类型的ViewModel子类型的实例,例如CheckBoxSettingDataVM
,AudioFileSettingDataVM
等。所有这些都是从继承的e> 设置数据虚拟机
更新3
我不想显式地分配ContentTemplate
属性,我想从项目(ViewModel)中获取容器(类型ContentPresenter
)从中我可以得到ViewModel隐式DataTemplate
中的根元素,它可以是AudioFileSelector
,ImageFileSelector
或其他类型。我需要ContentTemplate
属性不同于null
,这样我就可以存储对AudioFileSelector
的引用和ImageFileSelector
以及将来可能的其他设置。我将使用这些引用将一些设置从应用程序打开的文件加载到这些控件中
也许我做错了什么,但我仍然在学习MVVM。我认为如果我可以设置数据模板
的数据类型
,并且即使它有一个资源键,它仍然会自动应用于其范围内的ItemsControl
中,我的问题就会得到解决
更新4
我试图通过制定这个计划来更好地理解,我希望它能有所帮助(我意识到这只是复杂的事情,但这是我问题的一部分):
从代码隐藏中,您可以通过执行以下操作,通过ItemsControl
为给定的ViewModel对象检索实例化的DataTemplate
的根可视对象:
//假设您有权访问viewModel变量和MyItemsControl:
//我们检索生成的容器
var container=MyItemsControl.Ite