Стиль установки WPF c # с параметрами - PullRequest
0 голосов
/ 13 июня 2018

Я ищу способ назначить стиль с параметрами (большинство из них просто текст) и назначить на указанные блоки

<StackPanel Orientation="Horizontal">
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock x:Name="field1" Text="Field1"/>
        </StackPanel>
    </StackPanel>
    <StackPanel>
        <Button BorderThickness="0">
            <Button.Content>
                <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock  FontSize="10" Text="Default" Foreground="#FFCFCFCF" Margin="0" FontWeight="Black"/>
                    </StackPanel>
                </Border>
            </Button.Content>
        </Button>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <TextBlock x:Name="field2" Text="Field2"/>
        </StackPanel>
    </StackPanel>
    <StackPanel>
        <Button  BorderThickness="0">
            <Button.Content>
                <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="10" Text="RCC" Foreground="#FFCFCFCF" Margin="0" FontWeight="Black"/>
                    </StackPanel>
                </Border>
            </Button.Content>
        </Button>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <TextBlock x:Name="field3" Text="Field3"/>
        </StackPanel>
    </StackPanel>
    <Rectangle Width="1" Fill="Black" Height="42" VerticalAlignment="Center"/>
    <StackPanel Orientation="Horizontal">
        <Button  BorderThickness="0">
            <Button.Content>
                <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="10" Text="Custom" Foreground="#FFCFCFCF" FontWeight="Black"/>
                    </StackPanel>
                </Border>
            </Button.Content>
        </Button>
        <TextBox Width="90" Height="15"/>
        <Button  BorderThickness="0">
            <Button.Content>
                <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock FontSize="10" Text="Apply" Foreground="#FFCFCFCF" FontWeight="Black"/>
                    </StackPanel>
                </Border>
            </Button.Content>
        </Button>
    </StackPanel>
</StackPanel>

Есть 3 TextBlocks (field1, field2, field3), теперь этоесть какой-либо способ передать параметры (параметры строкового типа) в этот шаблон, и этот шаблон генерируется через цикл.А как это сделать?Конечно, я мог сделать все в c #, но подумал, что было бы намного проще просто создать поле (стека) и назначить параметры

<stackpanel Style="{StaticResource mystyle}" param1="hello" param2="this" param3="world"/>

Это было бы идеально, если бы это было возможно сделать таким образом.Если нет лучшего.Спасибо за помощь.

1 Ответ

0 голосов
/ 13 июня 2018

Вы можете объявить свои собственные стили и шаблоны элементов управления с дополнительным использованием DependencyProperties.

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

Как только это будет сделано, вы затем определите свой стиль, множество ресурсов для этого.Включите ваши свойства зависимостей как {TemplateBinding} в ваши пользовательские свойства.

Затем добавьте экземпляр вашего нового класса в форму и укажите, какой стиль использовать.У меня есть образец, показывающий использование ДВУХ стилей в одном классе.Я впервые начал с совершенно нового приложения WPF.В файле MainWindow.xaml.cs я определил свой собственный класс на основе типа UserControl (который затем может содержать любые другие элементы управления, такие как вложенные).Я добавил 3 свойства зависимости, чтобы отразить 3 возможных текстовых значения, которые вы хотите реализовать.

public class MyControl : UserControl
{
    public static readonly DependencyProperty MyText1Property =
        DependencyProperty.Register("MyText1", typeof(string),
        typeof(MyControl), new UIPropertyMetadata(""));

    public string MyText1
    {
        get { return (string)GetValue(MyText1Property); }
        set { SetValue(MyText1Property, value); }
    }


    public static readonly DependencyProperty MyText2Property =
        DependencyProperty.Register("MyText2", typeof(string),
        typeof(MyControl), new UIPropertyMetadata(""));

    public string MyText2
    {
        get { return (string)GetValue(MyText2Property); }
        set { SetValue(MyText2Property, value); }
    }


    public static readonly DependencyProperty MyText3Property =
        DependencyProperty.Register("MyText3", typeof(string),
        typeof(MyControl), new UIPropertyMetadata(""));

    public string MyText3
    {
        get { return (string)GetValue(MyText3Property); }
        set { SetValue(MyText3Property, value); }
    }
}

Далее, мое имя приложения StackOverflow для примера, а далее весь файл MainWindow.xaml.Разъяснение компонентов следует за кодом.

<Window.Resources>
    <Style TargetType="{x:Type myApp:MyControl}" x:Key="MyControlStyle1">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myApp:MyControl}" >
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{TemplateBinding MyText1}"/>
                        <TextBlock Text="{TemplateBinding MyText2}"/>
                        <TextBlock Text="{TemplateBinding MyText3}"/>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <Style TargetType="{x:Type myApp:MyControl}" x:Key="MyControlStyle">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myApp:MyControl}" >
                    <StackPanel Orientation="Horizontal" Grid.Row="0">
                        <TextBlock Text="{TemplateBinding MyText1}"/>
                        <StackPanel>
                            <Button BorderThickness="0">
                                <Button.Content>
                                    <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock  FontSize="10" Text="Default" Foreground="#FFCFCFCF" Margin="0" FontWeight="Black"/>
                                        </StackPanel>
                                    </Border>
                                </Button.Content>
                            </Button>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                <TextBlock Text="{TemplateBinding MyText2}"/>
                            </StackPanel>
                        </StackPanel>

                        <StackPanel>
                            <Button  BorderThickness="0">
                                <Button.Content>
                                    <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock FontSize="10" Text="RCC" Foreground="#FFCFCFCF" Margin="0" FontWeight="Black"/>
                                        </StackPanel>
                                    </Border>
                                </Button.Content>
                            </Button>
                            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                                <TextBlock Text="{TemplateBinding MyText3}"/>
                            </StackPanel>
                        </StackPanel>
                        <Rectangle Width="1" Fill="Black" Height="42" VerticalAlignment="Center"/>
                        <StackPanel Orientation="Horizontal">
                            <Button  BorderThickness="0">
                                <Button.Content>
                                    <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock FontSize="10" Text="Custom" Foreground="#FFCFCFCF" FontWeight="Black"/>
                                        </StackPanel>
                                    </Border>
                                </Button.Content>
                            </Button>
                            <TextBox Width="90" Height="15"/>
                            <Button  BorderThickness="0">
                                <Button.Content>
                                    <Border CornerRadius="18" BorderThickness="1" BorderBrush="#FFCFCFCF" >
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock FontSize="10" Text="Apply" Foreground="#FFCFCFCF" FontWeight="Black"/>
                                        </StackPanel>
                                    </Border>
                                </Button.Content>
                            </Button>
                        </StackPanel>
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>


    <!-- NOW, we can expand the custom properties-->
    <Style TargetType="{x:Type myApp:MyControl}" BasedOn="{StaticResource MyControlStyle}" />



</Window.Resources>


<Grid Height="150">
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
    </Grid.RowDefinitions>

    <myApp:MyControl MyText1="First String" MyText2="Second String" MyText3="Third String" 
        Style="{StaticResource MyControlStyle}"/>

    <myApp:MyControl MyText1="Another Line" MyText2="diff string" MyText3="all done" Grid.Row="1"/>

    <myApp:MyControl MyText1="Another Line" MyText2="diff string" MyText3="all done" Grid.Row="2"
        Style="{StaticResource MyControlStyle1}"/>

</Grid>

В верхней части основного объявления я добавил

    xmlns:myApp="clr-namespace:StackOverflow"

, это в основном утверждает, чтокогда в этом файле xaml я вижу префикс «myApp», он похож на «использование StackOverflow;»Команда как будто в коде.Так что теперь у меня есть доступ к пользовательскому классу (ам) или другим вещам в этом пространстве имен к xaml.

Далее я начинаю объявлять свой собственный "стиль" для пользовательского класса MyControl через

<Window.Resources>
    <Style TargetType="{x:Type myApp:MyControl}" x:Key="MyControlStyle1">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type myApp:MyControl}" >

...

Возможно, вы захотите создать отдельный ResourceDictionary, если вы имеете дело со многими стилями / шаблонами, используемыми в вашем приложении.Обратите внимание, что «Syle» и пользовательский «ControlTemplate» основаны на структуре класса «myApp: MyControl».Теперь я могу использовать свои элементы "MyText1", "MyText2", "MyText3" в шаблоне элемента управления.

x: Key = "MyControlStyle1" похоже на создание переменной с заданным именем, поэтому он можетиспользовать, если вам нужно явно сказать, какой стиль использовать.Этот первый стиль просто показывает, что 3 свойства «MyText» доступны, и текст получает свое значение от класса

Text="{TemplateBinding MyText1}"  

, с которым связан шаблон элемента управления (отсюда TemplateBinding).

Как только вы освоите основы, вы можете прославить свой шаблон, как у вас, с помощью вложенных панелей стека, что является нижним объявлением

<Style TargetType="{x:Type myApp:MyControl}" x:Key="MyControlStyle"> 

с другим именем x: Key.

Теперь, чтобы вам не приходилось явно добавлять xaml для вашего элемента управления и сказать ... кстати, используйте этот явный стиль MyControlStyle, у меня есть следующее

<Style TargetType="{x:Type myApp:MyControl}" BasedOn="{StaticResource MyControlStyle}" />

указывающий всякий раз, когда вы видите целевой тип «MyControl», по умолчанию стиль равен «MyControlStyle», поэтому мне не нужно постоянно помнить, чтобы сделать это.

Наконец-то реализуем его использование.Конец кода имеет простой элемент управления Grid с 3 строками.

<myApp:MyControl MyText1="First String" MyText2="Second String" MyText3="Third String" 
            Style="{StaticResource MyControlStyle}"/>

        <myApp:MyControl MyText1="Another Line" MyText2="diff string" MyText3="all done" Grid.Row="1"/>

        <myApp:MyControl MyText1="Another Line" MyText2="diff string" MyText3="all done" Grid.Row="2"
            Style="{StaticResource MyControlStyle1}"/>

Обратите внимание на первый случай, когда я МОГУ явным образом объявить стиль, который будет использоваться.Второй не имеет явного стиля в соответствии с настройками по умолчанию, но третий экземпляр явно заявляет об использовании упрощенного «MyControlStyle1», который был всего лишь 3-мя текстовыми блоками бок о бок, показывая, что вы можете иметь один класс и заставить его выглядеть по-другому по мере необходимости.

Редакция по вопросам / комментариям.

Если вы создаете эти элементы управления на основе цикла и динамически добавляете их, вы просто устанавливаете свойства соответственно в коде.Производительность не должна быть значительной, потому что класс уже объявлен, вы просто добавляете еще один в свой список.

foreach( var oneThing in YourListOfToBeAddedItems )
{
   var mc = new MyControl();
   mc.MyText1 = oneThing.TextFieldUsedForField1;
   mc.MyText2 = oneThing.FieldForSecondText;
   mc.MyText3 = oneThing.ThirdTextBasisForDisplay;
   // Now, add the "mc" to whatever your control is
   // can't confirm this line below as I dont know context
   // of your form and dynamic adding.
   YourWindowGridOrOtherControl.Controls.Add( mc );
}

Кроме того, поскольку стиль по умолчанию был определен, мне не нужно явно объявлять «Стиль» для элемента управления.

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