Изменить содержимое кнопки в стиле?

Я пытаюсь сделать что-то похожее на это:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid>
        <Button>
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Content"
                            Value="No mouse over" />
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver"
                                 Value="True">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <CheckBox Content="Mouse is over" />
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </Grid>
</Window>

Однако я получаю исключение XamlParseException во время выполнения с сообщением:

Невозможно добавить содержимое типа 'System.Windows.Controls.CheckBox' для объект типа "System.Object". Ошибка в объекте "System.Windows.Controls.CheckBox

Я на самом деле пытаюсь рисовать разные значки для содержимого кнопки в зависимости от внешних условий. Поэтому я фактически пытаюсь использовать DataTrigger, но приведенный выше пример упрощает проблему. Любые идеи?

Ответы

Ответ 1

Действительная ошибка возникает, потому что Visuals не может быть напрямую задана как значение Setter. Вы можете получить поведение, которое вы ищете, установив ContentTemplate с помощью DataTemplate или создав свой контент в качестве ресурса, либо определенного для кнопки, либо расположенного в другом месте.

<Button>
    <Button.Resources>
        <CheckBox x:Key="Local_MouseOverContent" Content="Mouse is over" />
    </Button.Resources>
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Content" Value="No mouse over" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Content"
                            Value="{StaticResource Local_MouseOverContent}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

<Button>
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Content" Value="No mouse over" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate DataType="Button">
                                <CheckBox Content="Mouse is over" />
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

Ответ 2

Замечание! Именно ваш пример работает в .NET Framework 4 без каких-либо изменений!!!!

  <Button>
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Content"
                        Value="No mouse over" />
                <Style.Triggers>
                    <Trigger Property="IsMouseOver"
                             Value="True">
                        <Setter Property="Content">
                            <Setter.Value>
                                <CheckBox Content="Mouse is over" />
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>

Ответ 3

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

Ответ 4

ПРЕДУПРЕЖДЕНИЕ: Это может быть не лучший или правильный способ сделать это. Убедитесь, что вы также прочитали другие ответы на этой странице.

Довольно уверен, что вы захотите использовать шаблон управления в подобной ситуации. Что-то вроде:


<style>
    <Setter Property="Content">
        <Setter.Value>
            <ControlTemplate>
                <Image Img="something.jpg" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</style>

И добавьте шаблон управления в триггер для наведения.

Здесь хорошая ссылка