WPF Button style won't apply to second button - wpf

I have two buttons that use a static common style:
<Button x:Name="BtnCreate" Height="22" Width="150" Style="{StaticResource Style.Button.Trash}"/>
<Button x:Name="aefae" Height="22" Width="150" Style="{StaticResource Style.Button.Trash}"/>
The style is very basic:
<Style TargetType="Button" x:Key="Style.Button.Trash"
BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal" >
<Image Source="{StaticResource Image.Trash}" Width="22" Height="22"/>
<Label Content="Save" VerticalAlignment="Center" Height="26" />
</StackPanel>
</Setter.Value>
</Setter>
</Style>
The style applies to the first button and display both the image an the text however the second button does not display anything except a grey button.
Why does the second button not use the static style?

As you're trying to add the same Content to two Buttons, elements (present in Style) cannot be added to two different Logical Parents. To avoid this, you can set x:Shared="False" to your style.

Related

Override or add some style properties in WPF

I am porting a Bootstrap theme to WPF and faced a problem: I can't change some properties using additional style for StackPanel. I have ResourceDictionary containing BtnBase base style and BtnPrimary, BtnSecondary etc. All of them were inherited from BtnBase and contain only color properties. BtnBase does not contain any margin rule. When I try to add margin rule for a current StackPanel, there is no effect. I read about styles and knew that more than one style can't be applied, styles in ResourceDictionary have higher priority and I should use BasedOn. But I need to copy and paste my style in the StackPanel and replace BasedOn for each button variant. Is there a way to bypass it and add margin property for all styles?
code:
<StackPanel Orientation="Horizontal" Height="32">
<StackPanel.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource BtnBase}>
<Setter Property="Margin" Value="0,0,10,0"/>
</Style>
</StackPanel.Resources>
<Button Style="{DynamicResource BtnPrimary}" Content="Primary" />
<Button Style="{DynamicResource BtnSecondary}" Content="Secondary" />
<Button Style="{DynamicResource BtnSuccess}" Content="Success" />
<Button Style="{DynamicResource BtnInfo}" Content="Info" />
<Button Style="{DynamicResource BtnWarning}" Content="Warning" />
<Button Style="{DynamicResource BtnDanger}" Content="Danger" />
<Button Style="{DynamicResource BtnLight}" Content="Light" />
<Button Style="{DynamicResource BtnDark}" Content="Dark" />
</StackPanel>
You can treat all buttons as Items in ListBox.
ListBox will create a ListBoxItem for each Button, and you can add Margin to those ListBoxItems, using ItemContainerStyle. That doesn't modify Buttons styles, but creates same effect.
In ItemContainerStyle I also change ListBoxItem template to undo hover, selection colors, etc, which can change appearance - just plain ContentPresenter is left.
ItemsPanel by default is vertical StackPanel, but I changed ItemsPanel and layout to horizontal StackPanel.
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Height="32"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<Button Style="{DynamicResource BtnPrimary}" Content="Primary" />
<Button Style="{DynamicResource BtnSecondary}" Content="Secondary" />
<Button Style="{DynamicResource BtnSuccess}" Content="Success" />
<Button Style="{DynamicResource BtnInfo}" Content="Info" />
<Button Style="{DynamicResource BtnWarning}" Content="Warning" />
<Button Style="{DynamicResource BtnDanger}" Content="Danger" />
<Button Style="{DynamicResource BtnLight}" Content="Light" />
<Button Style="{DynamicResource BtnDark}" Content="Dark" />
</ListBox>

Make an image act like a button in WPF

I have the below stackpanel that features 2 images. One of a tick and one of an exit.
<StackPanel Grid.Row="3" Orientation="Horizontal">
<Image Source="C:\Users\USER\Pictures\Tick.png" Height="100" Margin="55,10,0,5" HorizontalAlignment="Left" VerticalAlignment="Center" />
<Image Source="C:\Users\USER\Pictures\Exit.png" Height="88" Margin="75,10,20,5" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</StackPanel>
How am I able to make these 2 images act like a button? I know that you can use < button /> to create a new button, but I want to add a sort of property that will act as a button click when clicked.
Edit: I do not want the image to look like a button does with the outline and click effect. It just needs to be the image.
You could completely customize the appearance of a button but still keep its functionality by creating a custom template:
<Button Click="Button_Click">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Image Source="C:\Users\USER\Pictures\Tick.png" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
The above sample button should look exactly like an image but still be clickable like any other button.
Why don't you just make the image the Content of a Button?
<Button Height="100" Margin="55,10,0,5" HorizontalAlignment="Left" VerticalAlignment="Center">
<Image Source="C:\Users\USER\Pictures\Tick.png"/>
</Button>

I want to be able to specify a style for a tooltip on some MenuItems, how do I do that?

I want to specify a template for the tooltips of some MenuItem controls on my views. I've put the following into a resource dictionary:
<Style TargetType="{x:Type ToolTip}" x:Key="MenuItemToolTip">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<HeaderedContentControl>
<HeaderedContentControl.Header>
<TextBlock FontSize="20" Background="#2288C6" Foreground="White" Padding="3">Click to report a bug</TextBlock>
</HeaderedContentControl.Header>
<HeaderedContentControl.Content>
<StackPanel>
<TextBlock Margin="0,5">Please do <Run FontWeight="Bold">not</Run> change the send To email address.</TextBlock>
<TextBlock>Also, leave the <Run FontStyle="Italic">BUG: BOTS</Run> in the subject line alone.</TextBlock>
<!-- more text blocks, but removed for brevity -->
</StackPanel>
</HeaderedContentControl.Content>
</HeaderedContentControl>
</ControlTemplate>
</Setter.Value>
</Setter>
Then in one of the views I've tried using it like so:
<MenuItem Background="{x:Null}" Foreground="#FF706C6C" Command="{Binding ViewBugReportingCommand}">
<MenuItem.Style>
<Style Resources="{StaticResource MenuItemToolTip}" />
</MenuItem.Style>
<MenuItem.Header>
<Path Data="{StaticResource BugIconData}"
Stretch="Uniform"
Fill="#77000000"
Width="20"
RenderTransformOrigin="0.25,0.25"
Height="20" />
</MenuItem.Header>
At first I tried this, but this was just as bad:
<MenuItem Background="{x:Null}" Foreground="#FF706C6C" Command="{Binding ViewBugReportingCommand}" ToolTip="{StaticResource MenuItemToolTip}">
<MenuItem.Header>
<Path Data="{StaticResource BugIconData}"
Stretch="Uniform"
Fill="#77000000"
Width="20"
RenderTransformOrigin="0.25,0.25"
Height="20" />
</MenuItem.Header>
So, how do I get my style into a resource dictionary so that I can use it on some MenuItems, but not all?
The problem with your first approach is that Style.Resources accepts a ResourceDictionary but you are setting it to a Style
Your second approach does not work because you are applying a Style object to the ToolTip property. So an implicit ToolTip is created which tries to Render your style. But since Style is not a UIElement,
what you get is a TextBlock with it's Text property set to whatever text is returned from Style.ToString, which is the name of the Style class by default.
The simplest way here would be to explicitly create a ToolTip for each of your MenuItems and set the styles there. For example:
<MenuItem Background="{x:Null}" Foreground="#FF706C6C" Command="{Binding ViewBugReportingCommand}">
<MenuItem.ToolTip>
<ToolTip Style={StaticResource MenuItemToolTip} Content="Your Tooltip text" />
</MenuItem.ToolTip>
</MenuItem>
Another option would be to add an implicit style to the Resources property of the MenuItem so that it will be applied
to all ToolTips inside the visual tree of the MenuItem.
<MenuItem ToolTip="Hello">
<MenuItem.Resources>
<Style TargetType="{x:Type ToolTip}">
.. setters
</Style>
</MenuItem.Resources>
</MenuItem>
I prefer the former because it's the simplest.
You can specify the tooltip style directly by using the tooltip control like this:
<MenuItem Background="{x:Null}"
Foreground="#FF706C6C"
Command="{Binding ViewBugReportingCommand}">
<MenuItem.ToolTip>
<ToolTip Style="{StaticResource MenuItemToolTip}" />
</MenuItem.ToolTip>
...
</MenuItem>

Make form semi transparent to see form's background image

I'm using WPF (c#) form with background image (background imagebrush).
I want to make all the UI elements(button , title, textbox)... become semi-transparent so that they don't cover the image completely,
but the background image still being visible (not semi-transparent)
I would like a way we can do it without having to set all the opaque value of UI elements.
Maybe this could help
<Window.Resources>
<Style x:Key="transparentControls" TargetType="Button">
<Setter Property="Opacity" Value="0.1"/>
<Setter Property="Background" Value="Green"/>
</Style>
</Window.Resources>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="MyImage.jpg"/>
</Grid.Background>
<Button Height="24" Width="100" Style="{StaticResource transparentControls}" VerticalAlignment="Top" Content="Hey"/>
<Button Height="24" Width="100" Style="{StaticResource transparentControls}" Content="There"/>
<Button Height="24" Width="100" Style="{StaticResource transparentControls}" VerticalAlignment="Bottom" Content="Click Me"/>
</Grid>
Just try to put all your UI elements in a Canvas or Grid and set the Opacity of that parent element.
Like that:
<Canvas Opacity="1">
<Button Width="100" Height="100"></Button>
</Canvas>
I hope this was what you meant.

Monospace Margin between elements in WPF

I want the space between the child elements in, for example, StackPanel be the same. When using the same Margin for child elements, gap between neighbors doubles. I'm using a little trick to solve this, but it seems to me there is more elegant solution. May be you have one?
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="Margin" Value="4,4,0,4" />
...
</Style>
<Style x:Key="LastMyButtonStyle" TargetType="Button" BasedOn="{StaticResource MyButton}">
<Setter Property="Margin" Value="4" />
</Style>
I'm using MyButtonStyle for all buttons except the last one, which use LastMyButtonStyle.
Put the StackPanel in another container, i.e. a Border, and set its Margin to the same value as those of the Buttons:
<Border>
<StackPanel Orientation="Horizontal" Margin="2">
<Button Margin="2" Content="Button 1"/>
<Button Margin="2" Content="Button 2"/>
<Button Margin="2" Content="Button 3"/>
</StackPanel>
</Border>

Resources