Нестандартные элементы

93
15 декабря 2020, 00:30

Как создаются подобные элементы ?

  • Особенно если их необходимо воссоздавать (отображать) программно.

Достаточно просто ссылок, понятия не имею на какой запрос подобное гуглить.

Нашёл только то, что можно в Border поместить TextBlock и закруглить углы у Border

Или просто создать 2 Border, а у них внутри TextBlock, задать слои и 1 смещать относительно другого ?

Answer 1

Начните с этого:

<GroupBox Header="Text 1">
    <TextBlock Text="Text 2"/>
</GroupBox>

Затем, ПКМ по GroupBox в дизайнере и Edit Template>Edit a Copy..., вводите имя для стиля и нажмите OK, у меня добавился такой стиль:

<Window.Resources>
    <BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
    <Style x:Key="MyGroupBoxStyle" TargetType="{x:Type GroupBox}">
        <Setter Property="BorderBrush" Value="#D5DFE5"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupBox}">
                    <Grid SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="6"/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="6"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="6"/>
                        </Grid.RowDefinitions>
                        <Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="4" Grid.Column="0" CornerRadius="4" Grid.Row="1" Grid.RowSpan="3"/>
                        <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="4" CornerRadius="4" Grid.Row="1" Grid.RowSpan="3">
                            <Border.OpacityMask>
                                <MultiBinding ConverterParameter="7" Converter="{StaticResource BorderGapMaskConverter}">
                                    <Binding ElementName="Header" Path="ActualWidth"/>
                                    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
                                    <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
                                </MultiBinding>
                            </Border.OpacityMask>
                            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3">
                                <Border BorderBrush="White" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2"/>
                            </Border>
                        </Border>
                        <Border x:Name="Header" Grid.Column="1" Padding="3,1,3,0" Grid.Row="0" Grid.RowSpan="2">
                            <ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                        <ContentPresenter Grid.ColumnSpan="2" Grid.Column="1" Margin="{TemplateBinding Padding}" Grid.Row="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

Правим:

<Window.Resources>
    <BorderGapMaskConverter x:Key="BorderGapMaskConverter"/>
    <Style x:Key="MyGroupBoxStyle" TargetType="{x:Type GroupBox}">
        <Setter Property="BorderBrush" Value="Red"/>
        <Setter Property="BorderThickness" Value="2.5"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupBox}">
                    <Grid SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="20"/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="20"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="6"/>
                        </Grid.RowDefinitions>
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="4" CornerRadius="10" Grid.Row="1" Grid.RowSpan="3">
                            <Border.OpacityMask>
                                <MultiBinding ConverterParameter="20" Converter="{StaticResource BorderGapMaskConverter}">
                                    <Binding ElementName="Header" Path="ActualWidth"/>
                                    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
                                    <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}"/>
                                </MultiBinding>
                            </Border.OpacityMask>
                        </Border>
                        <Border x:Name="Header" Background="Black" CornerRadius="8" Grid.Column="1" Padding="15,0" Grid.Row="0" Grid.RowSpan="2">
                            <ContentPresenter ContentSource="Header" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                        <ContentPresenter Grid.ColumnSpan="2" Grid.Column="1" Margin="{TemplateBinding Padding}" Grid.Row="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid Margin="5">
    <GroupBox Style="{DynamicResource MyGroupBoxStyle}">
        <GroupBox.Header>
            <TextBlock Text="Text 1" FontSize="16" FontWeight="DemiBold" Foreground="White"/>
        </GroupBox.Header>
        <TextBlock Text="Text 2" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16" FontWeight="DemiBold"/>
    </GroupBox>
</Grid>

Получаем:

Answer 2

У вас есть несколько вариантов:

  1. Показан в предыдущем примере, когда вы создаете Стиль (Style) меняющий отображение элемента управления за счет переопределения Шаблона (Template). Подробнее про это можно посмотреть здесь. Там на раздел про шаблоны элементов управления обратите внимание.

  2. Вы можете создать пользовательский элемент управления (UserControl) у которого будет как у формы файл XAML и файл с кодом на C#. И в дальнейшем его использовать как и обычные контролы поставляемые в WPF. Подробнее про это можно посмотреть здесь.

Для начала проще использовать второй вариант.

  1. Создаете пустой WPF проект
  2. Правый клик на проекте Add → User Control
  3. В открывшемся окне задаете его имя. Я не менял.
  4. Определяете что у вас будет в рамках вашего контрола, я задал ширину и высоту, плюс добавил красный эллипс. У вас может быть любая комбинация контролов, которая необходима вам для решения задачи. Вот так выглядит XAML:

    <UserControl x:Class="WpfApp4.UserControl1"
                     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                     xmlns:local="clr-namespace:WpfApp4"
                     mc:Ignorable="d" 
                     Width="40" Height="40">
        <Grid>
            <Ellipse Fill="Red" />
        </Grid>
    </UserControl>
    
  5. Вот так будет выглядеть XAML главной формы:

    <Window x:Class="WpfApp4.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp4"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid x:Name="grMain">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
        </Grid>
    </Window>
    
  6. Ну и в коде главной формы прописываем следующий код:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
        }
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < 6; i++)
            {
                UserControl1 control = new UserControl1();
                Grid.SetRow(control, i);
                grMain.Children.Add(control);
            }
        }
    }
    
  7. Вот так это выглядит после запуска программы.

READ ALSO
Приведение строки к Decimal в VB.NET

Приведение строки к Decimal в VB.NET

Имеется строка 7780444, как ее правильно привести к типу Decimal ?

114
с# Нужно сделать так,чтобы оставался след курсора?

с# Нужно сделать так,чтобы оставался след курсора?

В Windows Forms необходимо,чтобы во время движения курсора за ним оставался следКак это сделать?

109
Точка входа в приложение C#

Точка входа в приложение C#

Я пытаюсь прикрутить к текущему приложению, которое расположено на Form1 запуск Form2 в качестве заставкиНо при попытке скомпилировать всё это...

114
mysql - left join и where

mysql - left join и where

Существует две таблицы, которые требуется соединить при помощи left join, а также подсчитать сумму строк, удовлетворяющих некоторому условиюПри...

138