2010-11-14 2 views
0

Я пишу приложение, которое загружается в записи из файла XML и использует их для заполнения форм. Это для карточной игры, поэтому я хочу, чтобы формы отображали разные поля и имели разные взгляды в зависимости от конкретной записи (в частности, в зависимости от поля «CardType» в записи).WPF - переосмысление наследования управления

В vanilla C# я бы создал базовое окно, в котором содержалась запись, а затем наследовала его для каждого конкретного типа, изменяя визуальные эффекты окна. Затем я проверил Тип, создаст правильное окно и заполнил его.

В 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); 
    } 
} 

Так что, когда он работает, я жду окно держа сетку, которая содержит метку, которая была его логическое дерево заменяется ControlTemplate и заполняется с помощью динамического связывания.

Извините за бессвязный вопрос, я не знаю, правильно ли я поступаю неправильно, или я должен отказаться от всего этого и подойти к нему по-другому.

+0

Я рекомендую использовать CardLayout как UserControl. Это будет намного проще редактировать. –

ответ

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.

Смежные вопросы