Пользовательская кнопка переключения WPF с ContentControl - PullRequest
0 голосов
/ 08 декабря 2018

Кажется, очень трудно добиться чего-то довольно тривиального в WPF ...

Мне нужно спроектировать кнопку переключения с особым внешним видом (и ощущением).Я сделал небольшой проект, чтобы продемонстрировать проблему.

«Пользовательский элемент управления ToggleButton»:

<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" 
             mc:Ignorable="d"  d:DesignHeight="450" d:DesignWidth="800"
             Name="Bla">
    <UserControl.Resources>
        <Style TargetType="ToggleButton">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Grid>
                            <Ellipse Width="300" Height="300" Fill="Yellow"/>
                            <ContentPresenter />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

    <ToggleButton 
        Width="300" Height="300">
        <ContentControl Content="{Binding ElementName=Bla, Path=MainContent}"/>
    </ToggleButton>
</UserControl>

Свойство зависимости:

public static DependencyProperty MainContentProperty = DependencyProperty.Register(
    "MainContent",
    typeof(object),
    typeof(UserControl1),
    null);

public object MainContent
{
    get => GetValue(MainContentProperty);
    set => SetValue(MainContentProperty, value);
}

Способ, которым я хочу использоватьcontrol:

<local:UserControl1>
    <TextBlock>Whatever</TextBlock>
</local:UserControl1>

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

Какой правильный способ сделатьэто?

=== Обновление ===

ОК, добираемся куда-то ... наконец-то ...

Теперь я получил это как пользовательский элемент управления:

<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:wpfApp4="clr-namespace:WpfApp4"
             mc:Ignorable="d"  d:DesignHeight="450" d:DesignWidth="800"
             Name="Bla">
    <UserControl.Resources>
        <Style TargetType="wpfApp4:UserControl1">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <ToggleButton>
                            <Grid>
                                <Ellipse Width="300" Height="300" Fill="Yellow"/>
                                <ContentPresenter Content="{Binding ElementName=Bla, Path=MainContent}" />
                            </Grid>
                        </ToggleButton>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>

        <ContentPresenter/>
</UserControl>

И вот как я это использую:

<local:UserControl1>
    <local:UserControl1.MainContent>
        <TextBlock>Whatever</TextBlock>
    </local:UserControl1.MainContent>
</local:UserControl1>

Это, наконец, дает мне кнопку переключения с примененным стилем (эллипс появляется) и текстовое поле также отображается.

Итак, это работает.Вы хотите сказать, что это должно работать?Или это можно упростить?

1 Ответ

0 голосов
/ 08 декабря 2018

Это должно быть больше похоже на

<local:UserControl1>
    <local:UserControl1.MainContent>
        <TextBlock>Whatever</TextBlock>
    </local:UserControl1.MainContent>
</local:UserControl1>

Но вы должны ожидать переопределения ContentControl, который был бы более адекватным, чем использование UserControl.

Кстати, почему вы поместили ContentControl внутриКнопка-переключатель?ToggleButton сам по себе является ContentControl, у него есть собственное свойство Content.

Обновление:

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

<ToggleButton>

    <TextBlock>Whatever</TextBlock>

    <ToggleButton.Style>
        <Style TargetType="{x:Type ToggleButton}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToggleButton}">
                        <Grid>
                            <Ellipse Width="300" Height="300" Fill="Yellow"/>
                            <ContentPresenter Content="{TemplateBinding Content}" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ToggleButton.Style>
</ToggleButton>

Ofcorse, если вы хотите использовать свой стиль в приложении, лучше определить стиль всловарь ресурсов (например, в App.xaml), дайте ему ключ и вызывайте его для каждой кнопки переключения, используя {StaticResource key}.

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

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