2010-11-14 90 views
0

我正在写一个应用程序,它从XML文件加载记录并使用它们填充表单。这是一个纸牌游戏,所以我希望表单显示不同的字段,并根据特定的记录(具体取决于记录中的'CardType'字段)有不同的外观。我会创建一个基本窗口,它保存一条记录,然后从每个特定类型继承它,改变窗口的视觉效果。然后我会检查Type,实例化正确的窗口并填充它。WPF - 反思控制继承

在WPF中,不允许从窗口继承,因此解决方案是使用单个窗口,然后根据具体情况使用样式/模板来调整窗口。

最初我创建了完全独立的窗口,传递了适当的一个类,该类持有用于设置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); 
    } 
} 

所以当它运行时,我期待一个窗口控股,其保存有其逻辑树替换为控件模板,并通过动态绑定填充标签的网格。

对不起,我不知道我是否以错误的方式做正确的事情,或者我应该废除所有这些,并以不同的方式接近它。

+0

我建议将你的CardLayout作为UserControl来实现。这将更容易编辑。 – 2010-11-14 23:16:18

回答

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属性。