Вы можете объявить свои собственные стили и шаблоны элементов управления с дополнительным использованием 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 );
}
Кроме того, поскольку стиль по умолчанию был определен, мне не нужно явно объявлять «Стиль» для элемента управления.