c# - 接口(interface) DataContexts 的 WPF 数据类型解析

标签 c# wpf xaml mvvm

这个问题在这里已经有了答案:





Automatic template selection in WPF not working with interface

(1 个回答)


4年前关闭。




我已经设置了一个通用对话框窗口,它接受 View 模型和标题,然后根据窗口的 XAML 显示。

例如,此代码设置窗口的标题和数据上下文并显示它:

public void ShowWindow(object viewModel, string title)
{
    var win = new DialogWindow()
    {
        Title = title,
        DataContext = viewModel
    };
    win.Show();
}

该窗口的代码隐藏不包含任何相关内容,但其内容呈现器的 XAML 如下所示:
<ContentPresenter x:Name="DialogPresenter" Content="{Binding}">
    <ContentPresenter.Resources>
        <DataTemplate DataType="{x:Type i:IMyInterface}" >
            <c:MyInterfacesControl/>
        </DataTemplate>
    </ContentPresenter.Resources>
</ContentPresenter>

问题是数据模板不会触发,因为传入的 View 模型是该接口(interface)的实现。但是,我希望代码检测 viewmodel 是否实现了它,并相应地使用模板。

通过使用转换器,我已经想到了一两种解决问题的方法,例如检查某些东西是否是转换器参数的实现。

但是这里有更简单的方法吗?

编辑:这与评论中建议的问题不同(编辑2:现在已经消失了);我不知道接口(interface)类型(可能会传入许多不同的接口(interface)类型),而是使用对象类型的数据上下文。

最佳答案

DataTemplate不适用于类型作为接口(interface),您通常应该将其与具体类型一起使用。

如果您定义了接口(interface)

public interface IA
{
    string A { get; set; }
}

和实现它的具体类型:
public class AA : IA
{
    public string A { get; set; }
}

然后按照数据模板不会通过 new A() 时使用;
<DataTemplate DataType="{x:Type local:IA}">
    <TextBlock Text="{Binding A}" />
</DataTemplate>

相反,您会看到类似

Application.AA



解决方案 1

可以使用具体类型,然后一切都会工作:
<DataTemplate DataType="{x:Type local:AA}">
    <TextBlock Text="{Binding A}" />
</DataTemplate>

解决方案 2

使用接口(interface)类型的属性并绑定(bind)到它(不是具体类型),这在 this answer 中有描述.

注意:您可以使用同名属性(property)归还不同的界面 (选择数据模板的那个)在你的具体类型中。

解决方案 3

您可以使用模板选择器。这真的很简单,给数据模板的键:
<DataTemplate x:Key="ia">
    <TextBlock Text="{Binding A}" />
</DataTemplate>

并选择在代码中使用哪一个:
public class TemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is IA)
            return (DataTemplate)((FrameworkElement)container).FindResource("ia");

        return base.SelectTemplate(item, container);
    }
}
ContentControl ContentTemplateSelector 属性,请勿使用 ContentPresenter为了这。

关于c# - 接口(interface) DataContexts 的 WPF 数据类型解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45375382/

相关文章:

wpf - 如何通过 XAML 设置 WPF 超链接文本

c# - C# 中的 Bitvector32 和 Bitarray

c# - 允许多内容自定义控件中的命名元素

c# - WPF 鼠标按下事件

c# - 如何在代码隐藏中访问 Button.Content 中的控件?

c# - 指南针 UI 和指针

c# - 将 XAML 导入 WPF RichTextBox

c# - 动态获取一个 DbSet

c# - 机器人框架 v4.如何清除turnContext.Activity.MembersAdded,以便再次发送欢迎消息

c# - 将 MSbuild 文件从 4.0 降级到 3.5