对于学校项目,我需要一个问题对象的选择性模板。根据其类型,我必须显示不同的类型(类型是:打开,多选和关闭)
我将模板定义为
<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
与setter。基于StackOverflow上显示的另一个示例。但是,此示例为我返回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; } }
}
我做错了吗?我该如何解决这个问题?
更新:它已经解决了。给定的示例工作正确。数据库给定的数据不正确,导致错误。
答案 0 :(得分:0)
DataTemplates旨在与System.Type
中的类型一起使用。它们是交换UI元素的简单方法,用于与特定类型进行交互。你正在做的可能是滥用这个。这就是原因。
为了以这种方式使用DataTemplates,你必须重构这个(我认为你有)
enum TestType { open, multiplechoice, closed }
class Mahveurmerder // view model
{
public TestType type {get;set;}
// snip
}
但是,为了正确使用DataTemplates,您必须将测试类型表示为实际类型。这就是我的意思:
// 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塞在它和它的结束标记之间。
现在,当然,正确的方式来执行您尝试做的事情是使用IValueConverter来转换{{1 (我希望你的应用程序中的枚举)是一个字符串表示。这个实现将是七八行,非常琐碎。你可以在这里找到很多例子,所以我会让你发现。
然后,您需要做的就是
type
并在你的ItemsControl.ItemTemplate中(摆脱所有其他废话)
<!-- up in your window's or app's Resources -->
<converters:MerTestTyerpCernverter x:Name="Duh" />
一旦你理解了模式,WPF就很容易了。如果你在兔子洞里停下来,停下来并重新考虑你正在做的事情 - 这可能是一种更容易的方法。
答案 1 :(得分:0)
如何设置type
属性?您能否验证这些值是否符合预期?
根据对象模型和您对QuestionContent
的绑定有效的声明,看起来您正确设置了DataContext层次结构,因此最可能的问题原因是数据本身。
我还注意到你没有在对象模型上实现INotifyPropertyChanged
,所以如果在绑定对象后设置它,那么UI就不知道它需要刷新。