条件数据模板 returns 对象

Conditional DataTemplate returns object

对于一个学校项目,我需要一个问题对象的选择性模板。根据其类型,我必须显示不同的类型(类型为:开放式、多项选择和封闭式)

我定义的模板如下

<ResourceDictionary>
    <UserControl.Resources>
        <DataTemplate x:Key="Open" >
            <WrapPanel>
                <Label Content="Open"/>
            </WrapPanel>
        </DataTemplate>
        <DataTemplate x:Key="multipleChoice" >
            <WrapPanel>
                <Label Content="multipleChoice"/>
            </WrapPanel>
        </DataTemplate>
        <DataTemplate x:Key="Closed" >
            <WrapPanel>
                <Label Content="Closed"/>
            </WrapPanel>
        </DataTemplate>
    </ResourceDictionary>
</UserControl.Resources>

如您所见,它现在只包含一个测试标签。 为了展示,我使用 ItemsControl 和设置器。基于此处在 Whosebug 上显示的另一个示例。但是这个例子 returns 对我来说是 System.Data.Entity.DynamicProxies,我不知道为什么。注释代码有效,因此可以访问属性。

<ItemsControl ItemsSource="{Binding SelectedInspection.Questionaire.Questions}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding}">
                    <ContentControl.Style>
                        <Style TargetType="ContentControl">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding type}" Value="Open">
                                    <Setter Property="ContentTemplate"
                                            Value="{StaticResource Open}" />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding type}" Value="multipleChoice">
                                    <Setter Property="ContentTemplate"
                                            Value="{StaticResource multipleChoice}" />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding type}" Value="Closed">
                                    <Setter Property="ContentTemplate"
                                            Value="{StaticResource Closed}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ContentControl.Style>
                </ContentControl>
            </DataTemplate>
            <!--
            <DataTemplate>
                <WrapPanel>
                    <Label Content="{Binding Path=QuestionContent}" />
                </WrapPanel>
            </DataTemplate>
            -->
        </ItemsControl.ItemTemplate>
    </ItemsControl>

我正在绑定我的问题模型,它看起来像这样

public class Question 
{
    public Question() 
    {
        this.Answers = new ObservableCollection<Answer>(); 
    } 

    [Key] 
    public virtual int Id { get; set; } 
    public String QuestionContent { get; set; } 
    public string OpenAnswer { get; set; } 
    public string type { get; set; } 
    public virtual ObservableCollection<Answer> Answers { get; set; } 
    public virtual Questionaire Questionaire { get; set; } }
}

我是不是做错了什么?我该如何解决这个问题?

更新:已解决。给定的示例工作正常。数据库给的数据不正确导致错误。

DataTemplates 旨在与类型一起使用...如 System.Type 中所示。它们是交换 UI 元素的简单方法,旨在与特定类型进行交互。你正在做的可能是滥用这一点。原因如下。

为了以这种方式使用 DataTemplates,您必须重构它(我认为您有)

enum TestType { open, multiplechoice, closed }
class Mahveurmerder // view model
{
    public TestType type {get;set;} 
    // snip
}

但是,为了正确使用数据模板,您必须将测试类型表示为实际类型。这就是我的意思:

// describes a type of test
abstract class TestType { }
// implementations of this type
class OpenBookTest : TestType {}
class ClosedBookTest : TestType {}
class MultipleTypeTest : TestType {}

并且您必须通过视图模型属性公开此类型的实例

class Mahveurmerder
{
  public TestType type {get;set;}
}

一旦您在模板上指定了数据类型:

<DataTemplate 
    xmlns:models="clr-namespace:ermagerdmerassinmernt.models"
    DataType="{x:Type OpenBookTest:}" >
    <WrapPanel>
        <Label Content="Open"/>
    </WrapPanel>
</DataTemplate>

ItemsControl 会自动拾取它们(是的,就这么简单)

<ItemsControl ItemsSource="{Binding SelectedInspection.Questionaire.Questions}" />

注意,ItemsControl 元素已关闭。没有数据触发 BS 塞在它和它的结束标签之间。

现在,当然,正确的方法来做你想做的事情是使用IValueConvertertype (我希望这是您的应用程序中的枚举)转换为字符串表示形式。这个的实现将是七八行,而且非常琐碎。你可以在这里找到很多例子,所以我会留给你去发现。

那么,您需要做的就是

<!-- up in your window's or app's Resources -->
<converters:MerTestTyerpCernverter x:Name="Duh" />

在你的 ItemsControl.ItemTemplate 中(摆脱所有其他废话)

<Label Content="{Binding type, converter={StaticResource Duh}}"/>

一旦您理解了模式,WPF 就非常容易了。如果您陷入困境,请停下来重新考虑您正在做的事情——可能有更简单的方法。

type属性是怎么设置的?您能否验证这些值是否符合您的预期?

根据对象模型和您关于绑定到 QuestionContent 的声明,看起来您的 DataContext 层次结构设置正确,因此最可能的问题原因是数据本身。

我还注意到您没有在对象模型上实现 INotifyPropertyChanged,因此如果它是在对象绑定到之后设置的,那么 UI 将不知道它需要刷新。