0

I want to make a brand new button, so that I create a usercontrol inherits Button to do this. Here is the XAML:

<Button x:Class="Uploader.PropertyButtonControl" 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:Uploader" mc:Ignorable="d" xmlns:s="clr-namespace:Svg2Xaml;assembly=Svg2Xaml" d:DesignHeight="450" d:DesignWidth="800"> <Button.Template> <ControlTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="0.6*"></RowDefinition> <RowDefinition Height="0.4*"></RowDefinition> </Grid.RowDefinitions> <Border Width="{Binding Path=ActualHeight,RelativeSource={RelativeSource Self}}" Grid.RowSpan="2" Background="{Binding IconBackground,Mode=TwoWay}"> <s:SvgShape Source="{Binding IconSource,Mode=TwoWay}"></s:SvgShape> </Border> <TextBlock Grid.Column="1" Text="{Binding ButtonTitle,Mode=TwoWay}"></TextBlock> <TextBlock Grid.Column="1" Grid.Row="1" Foreground="#575757" Text="{Binding ButtonContent,Mode=TwoWay}"></TextBlock> <Border Grid.ColumnSpan="2" Grid.RowSpan="2" BorderBrush="#cecece" BorderThickness="1" Visibility="Collapsed" Name="Bo"></Border> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter TargetName="Bo" Property="Visibility" Value="Visible"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Button.Template> </Button> 

And here is code-behind:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace Uploader { /// <summary> /// Interaction logic for PropertyButtonControl.xaml /// </summary> public partial class PropertyButtonControl : Button { public PropertyButtonControl() { InitializeComponent(); } public SolidColorBrush IconBackground { get { return (SolidColorBrush)GetValue(IconBackgroundProperty); } set { SetValue(IconBackgroundProperty, value); } } // Using a DependencyProperty as the backing store for IconBackground. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconBackgroundProperty = DependencyProperty.Register("IconBackground", typeof(SolidColorBrush), typeof(PropertyButtonControl),null); public ImageSource IconSource { get { return (ImageSource)GetValue(IconSourceProperty); } set { SetValue(IconSourceProperty, value); } } // Using a DependencyProperty as the backing store for IconSource. This enables animation, styling, binding, etc... public static readonly DependencyProperty IconSourceProperty = DependencyProperty.Register("IconSource", typeof(ImageSource), typeof(PropertyButtonControl), null); public string ButtonTitle { get { return (string)GetValue(ButtonTitleProperty); } set { SetValue(ButtonTitleProperty, value); } } // Using a DependencyProperty as the backing store for ButtonTitle. This enables animation, styling, binding, etc... public static readonly DependencyProperty ButtonTitleProperty = DependencyProperty.Register("ButtonTitle", typeof(string), typeof(PropertyButtonControl), null); public string ButtonContent { get { return (string)GetValue(ButtonContentProperty); } set { SetValue(ButtonContentProperty, value); } } // Using a DependencyProperty as the backing store for ButtonContent. This enables animation, styling, binding, etc... public static readonly DependencyProperty ButtonContentProperty = DependencyProperty.Register("ButtonContent", typeof(string), typeof(PropertyButtonControl), null); } } 

If I used it in a page as:

<local:PropertyButtonControl IconBackground="Red" ButtonTitle="123" ButtonContent="456"></local:PropertyButtonControl> 

After the program ran ,the content do not showed and color not changed? It seems is the binding problem.

But what's wrong with this? Thank you.

1 Answer 1

1

Your problem is the UserControl which is not adapted for a brand new button. You should rather use a CustomControl. Read this if you want more details.

Here is how we do:

Create a new class inheriting from the Button control in a separate file PropertyButtonControl.cs:

public class PropertyButtonControl : Button { //No need for Constructor and InitializeComponent public SolidColorBrush IconBackground[...] public static readonly DependencyProperty IconBackgroundProperty = DependencyProperty.Register("IconBackground", typeof(SolidColorBrush), typeof(PropertyButtonControl), null); public ImageSource IconSource[...] public static readonly DependencyProperty IconSourceProperty = DependencyProperty.Register("IconSource", typeof(ImageSource), typeof(PropertyButtonControl), null); public string ButtonTitle[...] public static readonly DependencyProperty ButtonTitleProperty = DependencyProperty.Register("ButtonTitle", typeof(string), typeof(PropertyButtonControl), null); public string ButtonContent[...] public static readonly DependencyProperty ButtonContentProperty = DependencyProperty.Register("ButtonContent", typeof(string), typeof(PropertyButtonControl), null); } 

Create a ResourceDictionary containing the XAML template in a separate file PropertyButtonControl.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:view="clr-namespace:StackTest.View"> <Style TargetType="{x:Type view:PropertyButtonControl }"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Button}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="0.6*"/> <RowDefinition Height="0.4*"/> </Grid.RowDefinitions> <Border Width="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}" Grid.RowSpan="2" Background="{Binding Path=IconBackground, RelativeSource={RelativeSource AncestorType=view:PropertyButtonControl}}"> </Border> <TextBlock Grid.Column="1" Text="{Binding Path=ButtonTitle, RelativeSource={RelativeSource AncestorType=view:PropertyButtonControl}}"/> <TextBlock Grid.Column="1" Grid.Row="1" Foreground="#575757" Text="{Binding Path=ButtonContent, RelativeSource={RelativeSource AncestorType=view:PropertyButtonControl}}"/> <Border Grid.ColumnSpan="2" Grid.RowSpan="2" BorderBrush="#cecece" BorderThickness="1" Visibility="Collapsed" Name="Bo"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter TargetName="Bo" Property="Visibility" Value="Visible"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary> 

Add this resource dictionary to your App.XAML resources:

<Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="View/PropertyButtonControl.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> 

Enjoy your control:

<local:PropertyButtonControl IconBackground="Blue" ButtonTitle="123" ButtonContent="456"/> 

I put all my files in a folder named View. You must adapt it to your own structure.

Sign up to request clarification or add additional context in comments.

1 Comment

OK,I always obscure the customcontrol and usercontrol, now I think I know what the difference between them. Thank you.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.