1 / 1 / 1
Регистрация: 27.05.2015
Сообщений: 86
1
WPF

Кнопка с изображением и текстом

27.03.2019, 13:24. Показов 3917. Ответов 6

Доброго времени суток.
Задача: сделать стиль кнопок для приложения. Вместо фона кнопки использую заранее подготовленные изображения.
Проблема: нашёл способ как задавать изображение кнопки по триггерам (обычное состояние кнопки - одно изображение. Когда наведён курсор - другое. Когда кнопка нажата - третье), однако после этого на кнопке не отображается текст.

ниже приведён стиль этой самой кнопки.


XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<Style x:Key="JustButtonStyle" TargetType="{x:Type Button}">
            <Style.Setters>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Image Source="pack://application:,,,/Images/button.png"/>
                        </ControlTemplate>
                    </Setter.Value>                    
                </Setter>
                <Setter Property="Control.FontFamily" Value="Times New Roman"/>
                <Setter Property="Control.FontSize" Value="9"/>
            </Style.Setters>
            
            <Style.Triggers>
                <Trigger Property="Control.IsMouseOver" Value="True">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="Button">
                                <Image Source="pack://application:,,,/Images/button_hover.png"/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Control.FontSize" Value="20"/>
                </Trigger>
 
                <Trigger Property="Button.IsPressed" Value="True">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="Button">
                                <Image Source="pack://application:,,,/Images/button_pressed.png"/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Control.FontSize" Value="20"/>
                </Trigger>
            </Style.Triggers>
        </Style>
Подытожу вопрос: как создать стиль кнопки таким образом, чтобы в зависимости от состояния кнопки (описанного выше) менялось её изображение и при этом был виден текст?
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.03.2019, 13:24
Ответы с готовыми решениями:

Нужна кнопка в виде шарика с текстом, и анимированный шарик с текстом.
где найти готовый? дополню: шарик с текстом у меня есть, но это просто плоский текст на сферическом...

Кнопка с изображением
Мне нужна кнопка с изображением.Загрузил изображение в стандартную.Но при наведении картинка с...

Кнопка с изображением и текстом
Что-то не могу разобраться как сделать кнопку, фон которой изображение? Делаю так &lt;button...

Адаптивный блок с изображением и текстом
Здравствуйте. Проблема: Есть блок, который должен быть равен ширине контента, внутри него...

6
Модератор
Эксперт .NET
10419 / 7395 / 2030
Регистрация: 21.04.2018
Сообщений: 22,317
Записей в блоге: 2
27.03.2019, 15:57 2
tagota, а если Вам надо поменять картинку, то что Вы будете делать? Стиль менять?
Надо вынести ссылки на картинки во внешние ключи (это один из вариантов).
Тогда в ресурсах кнопки изменяя ключи Вы сможете задать другие картинки не трогая стиль.
Вот пример такого стиля и его использования:
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    <Grid>
        <Grid.Resources>
            <Image x:Key="Image.Button.Default" Source="Resources/Стрелка Вверх.png"/>
            <Image x:Key="Image.Button.IsMouseOver" Source="Resources/Стрелка Вниз.png"/>
            <Image x:Key="Image.Button.IsPressed" Source="Resources/Стрелка Влево.png"/>
            <Style x:Key="JustButtonStyle" TargetType="{x:Type Button}">
                <Style.Setters>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <ContentControl x:Name="PART_ContentControl" Content="{DynamicResource Image.Button.Default}"/>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="Control.IsMouseOver" Value="True">
                                        <Setter TargetName="PART_ContentControl" Property="Content" Value="{DynamicResource Image.Button.IsMouseOver}"/>
                                    </Trigger>
                                    <Trigger Property="Button.IsPressed" Value="True">
                                        <Setter TargetName="PART_ContentControl" Property="Content" Value="{DynamicResource Image.Button.IsPressed}"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Control.FontFamily" Value="Times New Roman"/>
                    <Setter Property="Control.FontSize" Value="9"/>
                </Style.Setters>
            </Style>
        </Grid.Resources>
        <Button HorizontalAlignment="Left" VerticalAlignment="Top" Style="{Binding Mode=OneWay, Source={StaticResource JustButtonStyle}}" Width="50" Height="50"/>
        <Button HorizontalAlignment="Center" VerticalAlignment="Top" Style="{Binding Mode=OneWay, Source={StaticResource JustButtonStyle}}" Width="50" Height="50">
            <Button.Resources>
                <Image x:Key="Image.Button.Default" Source="Resources/Красный крестик.png"/>
                <Image x:Key="Image.Button.IsMouseOver" Source="Resources/Плюс.png"/>
                <Image x:Key="Image.Button.IsPressed" Source="Resources/Val_1.png"/>
            </Button.Resources>
        </Button>
    </Grid>
Добавлено через 1 минуту
Теперь касаемо текста.
У Вас в шаблоне нет элемента выводящего текст. Поэтому он и не выводится.
Где и как он должен выводиться?
Поверх картинки, снизу, сверху, по диагонали и т.д.

Добавлено через 10 минут
Вот пример вывода поверх рисунка по центру кнопки
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    <Grid>
        <Grid.Resources>
            <Image x:Key="Image.Button.Default" Source="Resources/Стрелка Вверх.png"/>
            <Image x:Key="Image.Button.IsMouseOver" Source="Resources/Стрелка Вниз.png"/>
            <Image x:Key="Image.Button.IsPressed" Source="Resources/Стрелка Влево.png"/>
            <Style x:Key="JustButtonStyle" TargetType="{x:Type Button}">
                <Style.Setters>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Grid>
                                    <ContentControl x:Name="PART_ContentControl" Content="{DynamicResource Image.Button.Default}"/>
                                    <TextBlock Text="{Binding Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" 
                                               TextWrapping="Wrap"
                                               HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="Control.IsMouseOver" Value="True">
                                        <Setter TargetName="PART_ContentControl" Property="Content" Value="{DynamicResource Image.Button.IsMouseOver}"/>
                                    </Trigger>
                                    <Trigger Property="Button.IsPressed" Value="True">
                                        <Setter TargetName="PART_ContentControl" Property="Content" Value="{DynamicResource Image.Button.IsPressed}"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Control.FontFamily" Value="Times New Roman"/>
                    <Setter Property="Control.FontSize" Value="9"/>
                </Style.Setters>
            </Style>
        </Grid.Resources>
        <Button HorizontalAlignment="Left" VerticalAlignment="Top" Style="{Binding Mode=OneWay, Source={StaticResource JustButtonStyle}}" Width="50" Height="50"/>
        <Button HorizontalAlignment="Center" VerticalAlignment="Top" Style="{Binding Mode=OneWay, Source={StaticResource JustButtonStyle}}" Width="50" Height="50">
            <Button.Resources>
                <Image x:Key="Image.Button.Default" Source="Resources/Красный крестик.png"/>
                <Image x:Key="Image.Button.IsMouseOver" Source="Resources/Плюс.png"/>
                <Image x:Key="Image.Button.IsPressed" Source="Resources/Val_1.png"/>
            </Button.Resources>
            Пример текста
        </Button>
    </Grid>
1
1 / 1 / 1
Регистрация: 27.05.2015
Сообщений: 86
28.03.2019, 10:38  [ТС] 3
А, понял, По сути мы переопределяем контрол заново в стиле, я правильно понял? то есть задаём где должно быть изображение, где текст или ещё какие элементы.

После использования Вашего совета, обнаружил некий баг, когда на окне расположено уже 2 и более кнопок:
Заключается это в том, что как только курсор переходит с кнопки 1 на кнопку 2 и затем убирается, то кнопка 1 становится без изображения, а кнопка 2 с ихображением. Ощущение, будто они не могут одновременно обращаться к одному ресурсу (изображению) и поэтому его перехватывает тот, кто обратился к нему последний, хотя звучит это глупо. Можете как-то прокомментировать этот момент, почему так происходит и как это пофиксить?
Спасибо!
Изображения
 
0
Модератор
Эксперт .NET
10419 / 7395 / 2030
Регистрация: 21.04.2018
Сообщений: 22,317
Записей в блоге: 2
28.03.2019, 11:40 4
Лучший ответ Сообщение было отмечено tagota как решение

Решение

Цитата Сообщение от tagota Посмотреть сообщение
Можете как-то прокомментировать этот момент, почему так происходит и как это пофиксить?
Да, действительно. Не ожидал такого.
Хотя можно было додуматься.

При рендеринге рисунок просто переставляется с места на место.
Надо для каждого шаблона инициализировать свой экземпляр.

Пришлось повозиться так как свойство Source не DP типа, а Binding. И DynamicResource для него задать нельзя.
Пришлось переделать через промежуточную привязку со свойством Tag.
Дурдом этот WPF! Порой простые вещи таким геморроем оборачиваются...
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    <Grid>
        <Grid.Resources>
            <sys:String x:Key="String.Image.Button.Default">Resources/Стрелка Вверх.png</sys:String>
            <sys:String x:Key="String.Image.Button.IsMouseOver">Resources/Стрелка Вниз.png</sys:String>
            <sys:String x:Key="String.Image.Button.IsPressed">Resources/Стрелка Влево.png</sys:String>
            <!--<Image x:Key="Image.Button.Default" Source="Resources/Стрелка Вверх.png"/>
            <Image x:Key="Image.Button.IsMouseOver" Source="Resources/Стрелка Вниз.png"/>
            <Image x:Key="Image.Button.IsPressed" Source="Resources/Стрелка Влево.png"/>-->
            <Style x:Key="JustButtonStyle" TargetType="{x:Type Button}">
                <Style.Setters>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Grid>
                                    <Image x:Name="PART_Image"  Tag="{DynamicResource String.Image.Button.Default}" Source="{Binding Tag, RelativeSource={RelativeSource Self}}"/>
                                    <TextBlock Text="{Binding Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" 
                                               TextWrapping="Wrap"
                                               HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="Control.IsMouseOver" Value="True">
                                        <Setter TargetName="PART_Image" Property="Tag" Value="{DynamicResource String.Image.Button.IsMouseOver}"/>
                                    </Trigger>
                                    <Trigger Property="Button.IsPressed" Value="True">
                                        <Setter TargetName="PART_Image" Property="Tag" Value="{DynamicResource String.Image.Button.IsPressed}"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="Control.FontFamily" Value="Times New Roman"/>
                    <Setter Property="Control.FontSize" Value="9"/>
                </Style.Setters>
            </Style>
        </Grid.Resources>
        <Button HorizontalAlignment="Left" VerticalAlignment="Top" Style="{Binding Mode=OneWay, Source={StaticResource JustButtonStyle}}" Width="50" Height="50"/>
        <Button HorizontalAlignment="Center" VerticalAlignment="Top" Style="{Binding Mode=OneWay, Source={StaticResource JustButtonStyle}}" Width="50" Height="50">
            <!--<Button.Resources>
                <Image x:Key="Image.Button.Default" Source="Resources/Красный крестик.png"/>
                <Image x:Key="Image.Button.IsMouseOver" Source="Resources/Плюс.png"/>
                <Image x:Key="Image.Button.IsPressed" Source="Resources/Val_1.png"/>
            </Button.Resources>-->
            Пример текста
        </Button>
    </Grid>
1
Рядовой
28.03.2019, 13:19
  #5

Не по теме:

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Дурдом этот WPF! Порой простые вещи таким геморроем оборачиваются...
да нормально. Логично же предположить, что отображение картинки - не свойство кнопки, было бы логичнее забиндить команду на Image, событие клик. По хорошему нужно было кастомный контрол писать.

0
1 / 1 / 1
Регистрация: 27.05.2015
Сообщений: 86
28.03.2019, 13:38  [ТС] 6
Лучший ответ Сообщение было отмечено Элд Хасп как решение

Решение

Большое спасибо! всё заработало, всё понятно, всё красиво.

Кому интересно будет:

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    <Window.Resources>
    .
    .
    .
        <sys:String x:Key="ButtonDefaultImg">pack://application:,,,/Images/button.png</sys:String>
        <sys:String x:Key="ButtonIsMouseOverImg">pack://application:,,,/Images/button_hover.png</sys:String>
        <sys:String x:Key="ButtonIsPressedImg">pack://application:,,,/Images/button_pressed.png</sys:String>
 
        <Style x:Key="JustButtonStyle" TargetType="{x:Type Button}">
            <Style.Setters>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Grid>
                                <Image x:Name="buttonImage" Tag="{DynamicResource ButtonDefaultImg}" Source="{Binding Tag, RelativeSource={RelativeSource Mode=Self}}"/>
                                <TextBlock x:Name="buttonText" Text="{Binding Content, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Button}}}"
                                            TextWrapping="Wrap"
                                            HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="Control.IsMouseOver" Value="True">
                                    <Setter TargetName="buttonImage" Property="Tag" Value="{DynamicResource ButtonIsMouseOverImg}"/>
                                </Trigger>
                                <Trigger Property="Button.IsPressed" Value="True">
                                    <Setter TargetName="buttonImage" Property="Tag" Value="{DynamicResource ButtonIsPressedImg}"/>
                                    <Setter TargetName="buttonText" Property="Control.FontSize" Value="8"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style.Setters>
        </Style>
    </Window.Resources>
0
Модератор
Эксперт .NET
10419 / 7395 / 2030
Регистрация: 21.04.2018
Сообщений: 22,317
Записей в блоге: 2
28.03.2019, 15:10 7
Цитата Сообщение от Рядовой Посмотреть сообщение
да нормально. Логично же предположить, что отображение картинки - не свойство кнопки, было бы логичнее забиндить команду на Image, событие клик. По хорошему нужно было кастомный контрол писать.
Я не за это, а то что свойство Image.Source оказывается не DP типа, а Binding.
К нему нельзя сделать привязку DynamicResource.
Наверное, специально так сделали, "чтобы жизнь малиной не казалась..."
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.03.2019, 15:10

Изображение под изображением с текстом
Нужна помощь: Нужно сделать так: , но если делать просто через &lt;br&gt;, то при изменении окна...

Кнопка с изображением
Создал окно WinApi добавил изображение, 3 кнопки, на каждую с которых нужно добавить изображение,...

кнопка с изображением
как загрузить файл чтобы на кнопке было его изображение? в книжке дан...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.