我正在编写一个应用程序,它从XML文件中加载记录并使用它们来填充表单。这是一个纸牌游戏,所以我希望表单显示不同的字段,并根据特定记录具有不同的外观(具体取决于记录中的'CardType'字段)。
在vanilla C#中,我会创建一个基本窗口,其中包含一个记录,然后从每个特定类型继承,改变窗口的视觉效果。然后我会检查Type,实例化正确的窗口并填充它。
在WPF中,不允许继承Windows,因此解决方案是使用单个窗口,然后根据具体情况使用样式/模板调整窗口。
最初我创建了完全独立的窗口,传递了一个包含记录数据的类,该类用于设置DataContext。
然而,现在我正在努力做正确的事情,我正在努力抓住确切的方法。我尝试在一个样式中创建一个控件模板,该样式包含用于保存我的字段的控件,并使用绑定来填充字段......
<Style TargetType="{x:Type Label}" x:Key="testLabel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Grid>
<Rectangle Fill="White" Stroke="Black" StrokeThickness="3" RadiusX="20" RadiusY="20" />
<DockPanel LastChildFill="False" Margin="10">
<DockPanel DockPanel.Dock="Top">
<Grid VerticalAlignment="Top" DockPanel.Dock="Left">
<Ellipse Height="25" Width="25" Stroke="Black" StrokeThickness="2" Fill="Red"/>
<TextBlock Name="textLevel" Foreground="Black" FontSize="15" TextAlignment="Center" VerticalAlignment="Center" Text="{Binding Level, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
<DockPanel DockPanel.Dock="Top">
<TextBlock Name="textType" Foreground="Black" FontSize="15" FontWeight="Bold" FontStyle="Italic" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="10, 0, 10, 0" DockPanel.Dock="Right" Text="{Binding CardType, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Name="textName" Foreground="Black" FontSize="20" FontWeight="Bold" Margin="10, 0, 10, 0" DockPanel.Dock="Left" Text="{Binding CardName, UpdateSourceTrigger=PropertyChanged}"/>
</DockPanel>
<TextBlock Name="textPronounciation" Foreground="DarkSlateGray" FontSize="12" Margin="10, 0, 10, 0" DockPanel.Dock="Top" Text="{Binding Pronounciation, UpdateSourceTrigger=PropertyChanged}"/>
</DockPanel>
<Rectangle Name="rectPicture" Width="280" Height="210" Margin="0, 5" DockPanel.Dock="Top"/>
<TextBlock Name="textLineage" Foreground="Black" FontSize="15" Margin="10, 0, 10, 0" DockPanel.Dock="Top" Text="{Binding Lineage, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Name="textFlavourText" Foreground="Black" FontSize="11" TextWrapping="Wrap" Margin="10, 0, 10, 0" DockPanel.Dock="Top" Text="{Binding FlavourText, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Name="textQuote" Foreground="Black" FontSize="11" TextWrapping="Wrap" Margin="10, 5, 10, 0" DockPanel.Dock="Top" Text="{Binding Quote, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Name="textAttribution" Foreground="Black" FontSize="9" FontWeight="Bold" TextWrapping="Wrap" HorizontalAlignment="Right" Margin="10, 0, 10, 0" DockPanel.Dock="Top" Text="{Binding Attribution, UpdateSourceTrigger=PropertyChanged}"/>
.
.
.
......但它没有填充。
控件模板中是否允许动态绑定,或者我应该做一些不同的事情?
(希望)所有相关代码如下:
来自调用函数:
private void ShowCard(CardDetails record)
{
CardLayout layout = new CardLayout(record);
CardWindow displayedCard = new CardWindow(layout);
displayedCard.Show();
}
CardLayout类 - 通过控件模板填充数据。我使用标签,因为它似乎是最简单的控件,因为我还是要替换它的逻辑树:
<Label x:Class="Cards.CardLayout"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Style="{StaticResource testLabel}">
</Label>
public partial class CardLayout : Label
{
public CardLayout()
{
InitializeComponent();
}
public CardLayout(CardDetails dataIn)
{
InitializeComponent();
Initialise(dataIn);
}
public void Initialise(CardDetails dataIn)
{
this.DataContext = dataIn;
}
}
CardWindow类 - 将CardLayout作为一个孩子持有 - 意图最终会有不同的窗口,其中包含不同数量的CardLayouts。
<Window x:Class="Cards.CardWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Grid Name="gridCard">
</Grid>
</Window>
public partial class CardWindow : Window
{
public CardWindow()
{
InitializeComponent();
}
public CardWindow(CardLayout dataIn)
{
InitializeComponent();
Initialise(dataIn);
}
public void Initialise(CardLayout dataIn)
{
gridCard.Children.Add(dataIn);
}
}
因此,当它运行时,我期待一个窗口,其中包含一个标签,该标签已将其逻辑树替换为ControlTemplate并通过动态绑定进行填充。
对于这个漫无边际的问题,我不知道,我不知道我是否以错误的方式做正确的事情,或者我应该废弃这一切并以不同的方式处理它。
答案 0 :(得分:0)
在等待答案时,我简化了一切,从硬连线值开始,然后逐渐添加一步,直到我开始工作。现在我已经充实了,我看不出我在做什么不同。
为了完整性,这是我的简化ControlTemplate,它与问题中的代码一起使用:
<Application.Resources>
<Style TargetType="{x:Type Label}" x:Key="testWindow4">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Grid>
<TextBlock Text="{Binding CardName}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
其中CardName是CardDetails中的String属性。