WPF: Button which is a path - c#

I have a bunch of Buttons in my application which look almost the same. The only difference between them is the path data that they use.
This is the style I have for the "minimize button" of my application:
<Style x:Key="MinimizeButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<!-- The border is here to make the entire "block" clickable.
Without it, only the actual path is clickable. -->
<Border Background="Transparent">
<Path Name="ThePath" Data="{StaticResource MinimizeIconPath}" Style="{StaticResource WindowButtonPath}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
As you can see, I'm basically just changing the control template to use a path instead of the default button stuff. But this declaration is only for the minimize button – I have a few other buttons, such as "maximize", "restore" and "close" to deal with now. The problem is that the styles for those buttons will be identical, with the only difference being the Data attribute of their Paths.
What would you recommend me to do to use as little code as possible?

User control?
http://www.codeguru.com/cpp/data/data-misc/xml/article.php/c12521/
http://www.codeproject.com/KB/WPF/XSButton.aspx

Related

How can I disable WPF button highlight when mouse over or when clicked in runtime?

I've this code in C# to create a button as a child of a StackPanel:
`
Button myButton = new Button();
//All button stuff (Background, text...).
myStackPanel.Children.add(myButton);
`
But, as every button, it highlights every time the mouse is over or when I click it. Is there any way to change that in an easy code (I'm still new to C#) can remove that highlight.
I don't know how to do this. I haven't seen anything explaining this and the only codes I could find were in XAML, and I didn't understand them so couldn't translate them to C#.
The problem is all the code I find is about retemplating the XAML code. What I need is to do what I mentioned in C#, as the control is created from scratch in C#.
I took a look at a few of the answers for this and didn't see any I liked much.
WPF controls are lookless, meaning they have fixed behaviour but not specific look to them. You can re template a wpf control to pretty much anything you can describe in xaml. Many wpf controls have quite complicated templates.
Here's one way to template a button as described.
I've put this style in my window's resources. Usually such styles are in resource dictionaries which are merged in app.xaml.
<Window.Resources>
<Style x:Key="NoMouseOverButtonStyle" TargetType="{x:Type Button}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="BorderBrush" Value="LightGray"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" >
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button Style="{StaticResource NoMouseOverButtonStyle}"
Content="This is my Button"
Click="Button_Click"
HorizontalAlignment="Left"
VerticalAlignment="Top"
/>
</Grid>
</Window>
The button references the style as a resource.
That style sets some defaults so the button has a border you can see but over ride.
The contentpresenter is critical because this is where whatever you make content of your button will appear.
If I set an actual value on a button then that will over ride the style.
Hence
<Button Style="{StaticResource NoMouseOverButtonStyle}"
Content="This is my Button"
Click="Button_Click"
HorizontalAlignment="Left"
VerticalAlignment="Top"
BorderBrush="Red"
/>
Gives me a red border on my button.
A lightgray border is rather simpler than a button has by default.
You could reproduce that. Maybe that'd be an interesting learning exercise.
Lookup the button template on msdn.
Google: "wpf button template msdn"
Take a look at that. Brace yourself - it is complicated.
See the button border brush is hard coded in the template?
Change the style above so it does the same.
Clue:
<Setter.Value>

Vertical alignment in Style

I have a very simple style. The code behind does nothing (for now).
<Style TargetType="{x:Type xxx:Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type fluent:Button}">
<Border BorderBrush="Black" BorderThickness="1,1,1,1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and then in the MainWindow I'll use it as:
<xxx:Button Content="1" FontSize="46" />
This causes the text to not be vertically centered. I asked a different question about this and the response was that its due to the way fonts scale and how they all scale differently. That's well and all, but how can I universally center the content in the border without knowing what it is? In the above example its just text, but it can be an icon or button, etc. Those all seem to center properly... is there a trick to getting it to work with text since every font will have a different "fudge factor"?

How to globally change the styling of the dottet lines around all focusble elements in one place?

From here I learned how to change the styling of dotted lines around focused button. I would like to apply the same thing on all focus-able elements of the current WPF application (or if not possible current page) in one place ( not doing separately for focus-able buttons, textboxes etc)
PS. Preferably in code behind
Define this Style in your App.Xaml .
<Application.Resources>
<Style x:Key="StyleFocusDefault" TargetType="{x:Type Control}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Control}">
<Grid>
<Rectangle StrokeThickness="2" Stroke="Black" StrokeDashArray="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
And then you can apply like : < ... FocusVisualStyle="{DynamicResource StyleFocusDefault}" .../>
This will change FocusVisualStyle for all Controls who have FocusVisualStyle property. You can further experiment with this appaorach for various controls.

How to change the styling of the dotted line around focused button globally in wpf?

I have multiple buttons and images in my WPF applications and would like to make the dotted line around focused buttons and focused images thicker for all of them.
I don't want to do it one by one for each component. Instead I am looking for a way that I can set the styling of the dotted line (dashed line) which indicates what component is focused globally for all of the components.
How to do it?
You can simply define an implicit Style targeting Button or Image or any other focusable Controls, place this Style is such as App.Resources or some separate ResourceDictionary:
<Style TargetType="Button">
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle StrokeThickness="2" Stroke="Black" StrokeDashArray="2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>

How can I set a border around a control during runtime in WPF?

I have an Image control on my WPF Form. How can I create a border around it during runtime?
Here's my XAML code:
<Image Margin="2.5"
Grid.Column="1" Grid.Row="0"
x:Name="Behemoth" Source="Images/Hero/Behemoth.gif" Stretch="Fill"
MouseEnter="HeroMouseEnter"
MouseLeave="HeroMouseLeave"
MouseDown="HeroMouseClick" />
Also, I want to know how to remove the border.
Maybe if I state my problem better there is an even better solution available.
I have many Images, and when a user says: "Hey, just show me the woman out of all the picture." I want a way to sort of highlight or draw the users attention to whatever images I need them to see. I was thinking about adding a border, but maybe that's too much work for something that can be solved easier.
Any help?
Although it's visually very different from a border, you could use an outter glow to signify the importance of the image. Then, you don't have to change the parent of the image.
Alternatively, you could use a custom Adorner to place a border around the image. Good info on Adorners can be found on msdn.
There's no straightforward way to do it, because the Border is a container, so you would have to remove the Image from its parent, put the Border instead, and put the Image back in the Border...
Another option would be to use templates :
<Window.Resources>
<ControlTemplate x:Key="imageWithBorder" TargetType="{x:Type Image}">
<Border BorderBrush="Red" BorderThickness="2">
<Image Source="{TemplateBinding Source}" />
</Border>
</ControlTemplate>
</Window.Resources>
...
<Image Name="image1" Source="foo.png"/>
When you want to put the border around the image, just assign the template to the image :
image1.Template = this.FindResource("imageWithBorder") as ControlTemplate;
For your stated needs, I suggest you use a ListBox with a custom ItemContainerStyle - one that always has a border but only makes it visible if the item is selected.
Here's the basic idea:
<ListBox ItemsSource="{Binding MyImageObjects}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="border">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ListBoxItem.IsSelected" Value="True">
<Setter ElementName="border" Property="BorderBrush" Value="Blue" />
<Setter ElementName="border" Property="BorderThickness" Value="2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

Categories

Resources