C# 如何从WPF中的DataTemplateSelector类中查找UserControl中的资源?
我正在创建自己的UserControl,在我的XAML中的UserControl.Resources部分下有两个不同的数据模板。我想根据listview中显示的对象的属性值,在这两个数据模板之间进行选择。为此,我创建了一个自定义的DataTemplateSelector类,并重写了SelectTemplate方法,该方法应该返回我想要使用的DataTemplate。但是,我不知道如何“查找”位于UserControls资源部分的数据模板,我看到的所有示例都只从窗口获取数据模板。在本例中,他们获取当前的主窗口,然后使用FindResource查找数据模板,如何以类似的方式获取我的用户控件:C# 如何从WPF中的DataTemplateSelector类中查找UserControl中的资源?,c#,.net,wpf,resources,wpf-controls,C#,.net,Wpf,Resources,Wpf Controls,我正在创建自己的UserControl,在我的XAML中的UserControl.Resources部分下有两个不同的数据模板。我想根据listview中显示的对象的属性值,在这两个数据模板之间进行选择。为此,我创建了一个自定义的DataTemplateSelector类,并重写了SelectTemplate方法,该方法应该返回我想要使用的DataTemplate。但是,我不知道如何“查找”位于UserControls资源部分的数据模板,我看到的所有示例都只从窗口获取数据模板。在本例中,他们获取
public override DataTemplate
SelectTemplate(object item, DependencyObject container)
{
if (item != null && item is AuctionItem)
{
AuctionItem auctionItem = item as AuctionItem;
Window window = Application.Current.MainWindow;
switch (auctionItem.SpecialFeatures)
{
case SpecialFeatures.None:
return
window.FindResource("AuctionItem_None")
as DataTemplate;
case SpecialFeatures.Color:
return
window.FindResource("AuctionItem_Color")
as DataTemplate;
}
}
return null;
}
上面的示例如下:我通常在DataTemplateSelector的构造函数中将UserControl作为参数从代码隐藏中实例化DataTemplateSelector,如下所示:
public class MyUserControl : UserControl
{
public MyUserControl()
{
Resources["MyDataTemplateSelector"] = new MyDataTemplateSelector(this);
InitializeComponent();
}
}
public class MyDataTemplateSelector : DataTemplateSelector
{
private MyUserControl parent;
public MyDataTemplateSelector(MyUserControl parent)
{
this.parent = parent;
}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
parent.DoStuff();
}
}
不是镇上最漂亮的女孩,但它能完成任务;)
希望这有帮助
<DataTemplate x:Key="addTemplate">
<Button Command="{Binding Path=AddCommand}">Add</Button>
</DataTemplate>
<DataTemplate x:Key="editTemplate">
<Button Command="{Binding Path=UpdateCommand}">Update</Button>
</DataTemplate>
<TemplateSelectors:AddEditTemplateSelector
AddTemplate="{StaticResource addTemplate}"
EditTemplate="{StaticResource editTemplate}"
x:Key="addEditTemplateSelector" />
添加
更新
仅限XAML 试试这个:
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item != null && item is AuctionItem)
{
AuctionItem auctionItem = item as AuctionItem;
switch (auctionItem.SpecialFeatures)
{
case SpecialFeatures.None:
return
((FrameworkElement)container).FindResource("AuctionItem_None")
as DataTemplate;
case SpecialFeatures.Color:
return
((FrameworkElement)container).FindResource("AuctionItem_Color")
as DataTemplate;
}
}
return null;
}
WinRT&Windows Phone解决方案涉及向上移动可视树,直到找到父控件:
protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container)
{
var parent = FindParent<MyParentControlType>(container as FrameworkElement);
if(parent != null)
{
if (item is Something)
return parent.Resources["TemplateForSomething"] as DataTemplate;
else if(item is SomethingElse)
return parent.Resources["TemplateForSomethingElse"] as DataTemplate;
else
// etc
}
else
{
return App.Current.Resources["SomeFallbackResource"] as DataTemplate;
}
}
public static T FindParent<T>(FrameworkElement element) where T : FrameworkElement
{
FrameworkElement parent = Windows.UI.Xaml.Media.VisualTreeHelper.GetParent(element) as FrameworkElement;
while (parent != null)
{
T correctlyTyped = parent as T;
if (correctlyTyped != null)
return correctlyTyped;
else
return FindParent<T>(parent);
}
return null;
}
受保护的覆盖Windows.UI.Xaml.DataTemplate SelectTemplateCore(对象项,Windows.UI.Xaml.DependencyObject容器)
{
var parent=FindParent(容器作为框架元素);
如果(父项!=null)
{
如果(项目是某物)
返回parent.Resources[“TemplateForSomething”]作为DataTemplate;
否则,如果(项目是某物)
返回parent.Resources[“TemplateForSomethingElse”]作为DataTemplate;
其他的
//等
}
其他的
{
返回App.Current.Resources[“SomeFallbackResource”]作为数据模板;
}
}
公共静态T FindParent(FrameworkElement元素),其中T:FrameworkElement
{
FrameworkElement parent=Windows.UI.Xaml.Media.VisualTreeHelper.GetParent(元素)作为FrameworkElement;
while(父级!=null)
{
T correctlyTyped=父项为T;
if(correctlyTyped!=null)
返回正确类型;
其他的
返回FindParent(父级);
}
返回null;
}
FindParent方法基于此处接受的答案:在XAML中没有办法做同样的事情吗?好的,这很好。。。但是知道推荐的方法是什么会很好,最好是用XAML来完成。。我也想知道一个更漂亮的方法。。但我认为这个问题实际上不能用XAML解决。您需要在代码背后提供某种引用,因此最简单的方法就是直接提供;)这似乎也是在Metro完成这项任务的唯一方法。由于Metro实施中的限制,其他选项都不起作用。这是否会创建一个保留周期?