WPF - Переосмысление управления наследованием - PullRequest
0 голосов
/ 15 ноября 2010

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

В 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, поскольку он казался самым простым элементом управления, так как я все равно собирался заменить его логическое дерево:

<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 и заполнено с помощью динамического связывания.

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

1 Ответ

0 голосов
/ 15 ноября 2010

В ожидании ответа я все упростил, начав с жестких значений, затем постепенно добавляя шаг, пока он не заработал.Теперь я все уточнил, я не вижу, что я делаю по-другому.

Для полноты вот мой упрощенный 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...