Modelo do botão personalizado no WPF

quero criar um modelo de botão simples com uma imagem e texto dentro dela. Mas quero manter o visual e a sensação do botão do sistema.

Como posso criá-lo, passo a passo?

P. S.: eu já tentei com CustomControl em WPF e BasedOn propriedade.

Author: Dave Clemmer, 2010-04-29

5 answers

Você pode fazer isso facilmente com um estilo e propriedades anexadas:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ap="clr-namespace:MyProject.Namespace.Path.To.ButtonProperties">
    ...
    <Style x:Key="ImageButton" TargetType="Button">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="{Binding Path=(ap:ButtonProperties.Image), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"></Image>
                        <ContentPresenter Content="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"></ContentPresenter>
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    ...
</ResourceDictionary>

E

public class ButtonProperties
{
    public static ImageSource GetImage(DependencyObject obj)
    {
        return (ImageSource)obj.GetValue(ImageProperty);
    }

    public static void SetImage(DependencyObject obj, ImageSource value)
    {
        obj.SetValue(ImageProperty, value);
    }

    public static readonly DependencyProperty ImageProperty =
        DependencyProperty.RegisterAttached("Image", typeof(ImageSource), typeof(ButtonProperties), new UIPropertyMetadata((ImageSource)null));
}

Depois Em marcação:

<Button Style="{StaticResource ImageButton}" ap:ButtonProperties.Image="{StaticResource MyImage}" Content="Test">
</Button>

Este exemplo parece bastante hediondo, mas você pode facilmente mudar o StackPanel para um Grid ou algo semelhante para restringir a proporção da imagem. A utilização do ContentPresenter permite-lhe preservar o comportamento de um botão que lhe permite colocar qualquer UIElement lá dentro, mantendo o Suporte de comandos, etc.

 34
Author: jeffora, 2012-08-13 23:09:16

Finalmente criei um botão com imagem + texto dentro dele:

Abaixo está o código Completo:

Passo 1: Criar um novo controlo de utilizador chamado: ImageButtonUC

<UserControl Name="ImageButton" x:Class="WpfApp.ImageButtonUC"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Button VerticalAlignment="Top" Width="100" Height="25" Click="button_Click"> 
            <Button.Content>
                <StackPanel Orientation="Horizontal">
                    <Image Width="16" Height="16" Margin="5,0,5,0" Source="{Binding ElementName=ImageButton, Path=Image}"/>
                    <TextBlock Text="{Binding ElementName=ImageButton, Path=Text}"/>
                </StackPanel>
            </Button.Content>
        </Button>
    </Grid>
</UserControl>

Passo 2: Editar O ImageButtonUC.xaml.cs

public partial class ImageButtonUC : UserControl
    {
        public event RoutedEventHandler Click;

        public ImageButtonUC()
        {
            InitializeComponent();

        }

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }


        public static readonly DependencyProperty TextProperty =
          DependencyProperty.Register("Text", typeof(string), typeof(ImageButtonUC), new UIPropertyMetadata(""));

        public ImageSource Image
        {
            get { return (ImageSource)GetValue(ImageProperty); }
            set { SetValue(ImageProperty, value); }
        }

        public static readonly DependencyProperty ImageProperty =
           DependencyProperty.Register("Image", typeof(ImageSource), typeof(ImageButtonUC), new UIPropertyMetadata(null));


        private void button_Click(object sender, RoutedEventArgs e)
        {

            if (null != Click)

                Click(sender, e);

        }

    }

Passo 3: no seu xaml pode usá-lo desta forma: Adicionar o espaço de nomes como

xmlns:Local="clr-namespace:WpfApp"

E usá-lo como:

<Local:ImageButtonUC x:Name="buttonImg" Width="100" Margin="10,0,10,0" Image="/WpfApp;component/Resources/Img.bmp" Text="Browse..." Click="buttonImg_Click"/>
Nota: a minha imagem é captada na pasta de recursos toma.

Referência:

Http://blogs.msdn.com/knom/archive/2007/10/31/wpf-control-development-3-ways-to-build-an-imagebutton.aspx

 6
Author: Archie, 2010-04-29 05:37:43

Se você não quer escrever qualquer código-atrás, há outra maneira de fazer isso (inspirado pela resposta de jeffora). Pode usar o campo de conteúdo do controlo para colocar o URI na imagem que deseja ver no seu botão:

<Button Content="https://www.google.com/images/srpr/logo3w.png" Height="100" Width="200" Style="{DynamicResource ButtonStyle1}"/>

E depois poderá editar o estilo do botão por omissão para se parecer com isto:

<Style>
...
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type Button}">
            <Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true">
                <Image x:Name="theImage" Source="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Margin="4,0,0,0">
                    <Image.ToolTip>
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Image.ToolTip>
                </Image>
            </Microsoft_Windows_Themes:ButtonChrome>
            <ControlTemplate.Triggers>
                ...
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Setter.Value>
</Setter>
</Style>

A magia está na fonte=(ligando ...}' parte. Tem funcionado bem para mim ter a dica lá para depurar as imagens em falta/alteradas -- mas pode ser facilmente removida como bem.

 2
Author: dogracer, 2013-01-24 17:31:41
Aqui está a minha solução!
<Button Content="Browse" Margin="10" Name="btBrowse">
            <Button.Template>
                <ControlTemplate>
                    <StackPanel Orientation="Vertical" Height="50" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Center">
                        <Image Source="MyIcons\browse.png" Height="30" />
                        <TextBlock Text="{Binding ElementName=btBrowse, Path=Content}" VerticalAlignment="Center" HorizontalAlignment="Center" />
                    </StackPanel>
                </ControlTemplate>
            </Button.Template>
        </Button>

O resultado está abaixo:

screenshot

 0
Author: Dave NP, 2017-07-25 10:01:10
Outra resposta: melhorar o u / dogracer e o U / Dave NP:
<Button Content = "{Binding object}" >
    <Button.Style >
        <Style TargetType="Button">
            <Setter Property = "ContentTemplate" >
                <Setter.Value >
                    <DataTemplate >
                        <StackPanel >
                            <Image  Source="{Binding Path=Content.ImageUrl, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" >
                                <TextBlock Text = "{Binding Path=Content.Text,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" />
                        </ StackPanel >
                    </ DataTemplate >
                </ Setter.Value >
            </ Setter >
        </ Style >
    </ Button.Style >
</ Button >
  1. Content is the bound to 'object' with 'ImageUrl' and' Text ' Properties.
  2. Isto funciona num controlo do utilizador fora da Assembleia principal.
  3. O estilo é o de um botão regular
 0
Author: Declan Taylor, 2017-09-17 00:31:48