指定默认的空 DataTemplate 而不是默认的 'ToString()' DataTemplate
Posted
技术标签:
【中文标题】指定默认的空 DataTemplate 而不是默认的 \'ToString()\' DataTemplate【英文标题】:Specify a default empty DataTemplate instead of the default 'ToString()' DataTemplate指定默认的空 DataTemplate 而不是默认的 'ToString()' DataTemplate 【发布时间】:2009-04-02 14:03:36 【问题描述】:wpf 应用程序中的默认 DataTemplate 显示 .ToString()
方法的结果。我正在开发一个应用程序,其中默认的 DataTemplate 不应该显示任何内容。
我试过了:
<Grid.Resources>
<DataTemplate DataType="x:Type System:Object">
<Grid></Grid>
</DataTemplate>
</Grid.Resources>
但这不起作用。如果不为应用程序中的每个类类型指定特定的 DataTemplate,有谁知道这是否可行?
【问题讨论】:
【参考方案1】:如果您使用 MVVM 模式并且有一个所有 ViewModel 类都派生自的抽象类,则可以使用该类而不是 System.Object:
<Grid.Resources>
<DataTemplate DataType="x:Type vm:VMBase">
</DataTemplate>
</Grid.Resources>
【讨论】:
你刚刚救了我的命。当然不是字面意思,但这正是我想要的【参考方案2】:我知道没有办法做到这一点。根据 Joe 下面的评论,WPF 明确禁止为类型 Object
指定 DataTemplate
。
根据您的具体要求,搜索与特定类型匹配的DataTemplate
可能会更容易。如果你找到一个,使用它。否则,什么也不显示。例如:
<ContentControl Content="Binding YourContent" ContentTemplateSelector="StaticResource MyContentTemplateSelector"/>
在您的选择器中(显然是伪代码):
var dataTemplateKey = new DataTemplateKey() DataType = theType; ;
var dataTemplate = yourControl.FindResource(dataTemplateKey);
if (dataTemplate != null)
return dataTemplate;
return NulloDataTemplate;
【讨论】:
“WPF 将对象与其 DataTemplate 按确切的运行时类型匹配”——不正确。如果添加 DataType=BaseClass 的 DataTemplate,它也会匹配 SubClass。我已经看到它工作了。不幸的是,该框架明确不允许为 System.Object 制作 DataTemplate;您会收到运行时错误“类型 'DataTemplateKey' 构造失败。DataTemplate.DataType 不能是 Object 类型。” 你是对的。我在考虑不会自动继承的样式。更新我的答案。谢谢。【参考方案3】:我使用 Nullable,适合我的情况。
<DataTemplate DataType="x:Type sys:Nullable">
<!-- Content -->
</DataTemplate>
【讨论】:
【参考方案4】:我不确定是否要替换默认的 DataTemplate,但您可以使用 ValueConverter 在某些类型的情况下传递显示 ToString,否则可以使用空字符串。这是一些代码(注意 typeb 文本块上没有转换器来显示它正常的样子):
.xaml:
<Window x:Class="EmptyTemplate.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:EmptyTemplate"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<loc:AType x:Key="atype"/>
<loc:BType x:Key="btype"/>
<loc:TypeConverter x:Key="TypeConverter"/>
</Window.Resources>
<StackPanel>
<Button Content="Binding Source=StaticResource atype, Converter=StaticResource TypeConverter"/>
<Button Content="Binding Source=StaticResource btype, Converter=StaticResource TypeConverter"/>
<TextBlock Text="Binding Source=StaticResource atype, Converter=StaticResource TypeConverter"/>
<TextBlock Text="Binding Source=StaticResource btype"/>
</StackPanel>
</Window>
.xaml.cs:
namespace EmptyTemplate
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
public Window1()
InitializeComponent();
public class AType
public class BType
public class TypeConverter : IValueConverter
public DataTemplate DefaultTemplate get; set;
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
if (value.GetType() == typeof(AType))
return value.ToString();
return DefaultTemplate;
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
throw new NotImplementedException();
#endregion
【讨论】:
【参考方案5】:这是一个关于如何使用选择器(IMO 的最佳方式)执行此操作的工作示例:
public class EmptyDefaultDataTemplateSelector : DataTemplateSelector
public override DataTemplate SelectTemplate(object item, DependencyObject container)
if (item != null)
var dataTemplateKey = new DataTemplateKey(item.GetType());
var dataTemplate = ((FrameworkElement) container).TryFindResource(dataTemplateKey);
if (dataTemplate != null)
return (DataTemplate) dataTemplate;
return new DataTemplate(); //null does not work
【讨论】:
【参考方案6】:我偶然发现了一些东西。我正在使用自定义依赖属性在用户控件上设置 Datacontext,该用户控件具有基于类型(在我的情况下为实体)的 Datatemplates 的内容控件。由于我有几种不同类型的实体,我的自定义依赖属性是
` typeof(object)
这是我用来绑定到 ContentControl 的数据上下文的设备。
public object MySelectedItem
get return (object)GetValue(Property1Property);
set SetValue(Property1Property, value);
public static readonly DependencyProperty Property1Property
= DependencyProperty.Register(
"MySelectedItem",
typeof(object),
typeof(PromotionsMenu),
new PropertyMetadata(false)
);
这样使用:
MySelectedItem = SomeEntity;
我发现我也可以这样使用它:
MySelectedItem = "some text";
上下文控件会打印一些文本作为其上下文。
MySelectedItem = "";
适用于完全空白的上下文。
`
【讨论】:
以上是关于指定默认的空 DataTemplate 而不是默认的 'ToString()' DataTemplate的主要内容,如果未能解决你的问题,请参考以下文章
当 ContentControl 的内容为空或为空时,在 ContentControl 中显示默认的 DataTemplate?
FCM点击应用处于后台状态时如何打开用户指定的活动而不是默认活动