Getting a templated button's command to work - wpf

I've used a control template to change the appearance of a button in a trivial way. It now looks different, but does not behave like a button. There are really two problems:
The button's command is never executed
After clicking on the button, it appears selected (i.e., the ellipse turns into an ugly blue rectangle)
Here's the general idea:
<Button Command="{x:Static commands:...}"
CommandParameter="{Binding}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Ellipse Fill="{Binding ...}"
.../>
</ControlTemplate>
</Button.Template>
</Button>

There's no reason this should be happening. I put together a test using ApplicationCommands.Copy and the command fired just fine. Could be your CommandBinding isn't working properly.
I also didn't see this based on copying your sample XAML and just setting Fill="Green". You can try setting FocusVisualStyle="{x:Null}" on the Button.

The problem turned out to be that Fill was bound to a value that could be null. If the Fill brush is null rather than transparent, then there's nothing to click and the command doesn't get executed. As Drew mentioned, with a solid fill, the button works correctly.
Takeaway lesson: if you want to hide your shape but still have it respond to user interaction, use a transparent brush, not a null brush.

I had a similar problem with a custom templated button:
<my:UniButton Command="{Binding MyCommand}"/>
The binding didn't work until adding a RelativeSource:
<my:UniButton Command="{Binding MyCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=my:CustomPanel}}"/>
where CustomPanel is a control where my button lies.
Withal I had a simple button on the same panel, but it worked fine even without RelativeSource.

Related

Button/Image Switch resource using click, MouseEnter and MouseLeave

I'm trying to change an image using events like Click, MouseEnter and MouseLeave. In first place I tried to do it with Buttons in order to have "Click" event too, but I don't know how to remove that lightblue background that appears by default when I put the mouse over the button with a png background.
After this, I tried to use , setting the resource image.png in its Source.
The main problem is that I don't know what to do in code-behind to change between Image Resources in order to change the Source of the control.
I want to know too if I can use a "Click Event" with an control
Update1:
Ok, I tried it by using Binding
For now I think its solved, but I have another problem.
I don't know exactly how to remove that "border". I tried to put the borderbrush property of the buttons to 0, but it seems to be another property or another control.
UI
Thanks.
You can put an image as the content of a button, and add an Click event to that Button. This way, an event gets called when you press the button.
<Button Margin="0,10" Name="mainButton" Click="mainButton_Click">
<Button.Content>
<Image Source="C:/reference-to-image" Height="30"/>
</Button.Content>
</Button>
In the background you can than change the Picture.
This question shows how to do that in the background.
WPF Image UriSource and Data Binding using http:\\ URL
PS. If you want to change the behavior of controls on certain events things like pressing the left mouse button on it, you have to overwrite the event triggers using
<Style TargetType="TextBlock">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
...
Hope this helps.
UPDATE
You can set the BorderThickness to 0 and than set the Value of the Padding Property to 0. The Button Control has a predefined padding value, which makes it look like it has a border.
Padding is the space inside the control and the content e.g the space between the button and the picture
<StackPanel Orientation="Horizontal">
<Button Click="Button_Click" Padding="0" BorderThickness="0">
<Image Source="link-to-pic" Height="100"/>
</Button>
<Button Click="Button_Click" Padding="0" BorderThickness="0">
<Image Source="link-to-pic" Height="100"/>
</Button>
</StackPanel>

Execute command on mouse click on image control wpf

There is a command property in wpf that I am trying to execute on an image click. I am basically changing the style of a scroller. I downloaded sample styles from here and after changing my style I end up with something like:
ok so let me explain. on the top there is an arrow pointing upwards on top of an image. I plan to get rid of the top arrow but the reason why I need it is because in the xaml it has a command that when clicked it scrolls upward. the code for that up arrow is:
<RepeatButton
Style="{StaticResource ScrollBarButton}"
Margin="0,15,0,0"
VerticalAlignment="Top"
Background="#FFFFFFFF"
Grid.Row="0"
Command="{x:Static ScrollBar.LineUpCommand}" <!-- This is the line that enables to scroll upwards when clicked -->
theme:ScrollChrome.ScrollGlyph="UpArrow"
RenderTransformOrigin="0.5, 0.5">
<RepeatButton.RenderTransform>
<ScaleTransform ScaleX="4" ScaleY="2"/>
</RepeatButton.RenderTransform>
</RepeatButton>
In short I am interested in the following property:
Command="{x:Static ScrollBar.LineUpCommand}"
It would be nice if I could get rid of the top arrow and place that command in the image instead. The problem is that the image control does not have the property command. I know I can make the alpha of the top arrow equal to 0 and make it appear like there is only an image but I am curios of understanding how does this work and moreover I would like to add more functionality such as changing the image appearance on mouse enter etc..
Create a button with control template just having an image and bind to the
Command of the button. More on this can be found here:
Attach ICommand in WPF UserControl
Or try using eventtocommand available in mvvm light tookit

Copy Property to Clipboard

I have a string property in my ViewModel/Datacontext and want a simple button that copies its contents to the clipboard. Is this possible to do from XAML, or I do I need to handle the button click event (or use an ICommand) to accomplish this? I thought the following would work, but my button is always greyed out:
<Button Width="100" Content="Copy" Command="ApplicationCommands.Copy"
CommandTarget="{Binding MyStringProperty}"/>
The ApplicationCommands are expecting to be in a Toolbar or Menu which will give them FocusScope based on RoutedUICommands. If your button is outside a Toolbar or Menu, then you need to explicitly declare the focus scope:
<Button
Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"
Command="ApplicationCommands.Copy"
FocusManager.IsFocusScope="True"/>
The CommandTarget is used to declare which element will provide the FocusScope which means that the Copy button will only be enabled whenever the element declared in the CommandTarget has focus, and in the case of copy, has text highlighted:
<Button
Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}"
Command="ApplicationCommands.Copy"
CommandTarget="{Binding ElementName=MyElement}" />
In answer to your specific question, you'd need to intercept the ApplicationCommands.Copy command to get/set your ViewModel's MyStringProperty; and to be honest, I'm not sure where to even start to figure that one out. Maybe someone smarter around here could provide that piece of the puzzle.

XAML: Get parent background

I need to set a control's background to the color of the parent's background in XAML. Why not simply make the background transparent? It's a button with a drop shadow, so I need to set the background; otherwise, the drop shadow shows through.
So, from my control's markup, how do I set the Background property equal to whatever the parent (host) Background is? Thanks for your help.
You should be able to set the binding using:
<Button Background="{Binding Path=Background, RelativeSource={RelativeSource Mode="FindAncestor" AncestorType="{x:Type Control}" AncestorLevel="1"}}" />
Since Background is defined for any "Control", this should grab the control one ancestor up the tree, and use it's background.
Another option to consider would be to just make a button style that shows the background as transparent, but actually still draws the drop shadow/border. This would allow it to work on any UIElement.
I am going to leave Reed's answer as accepted, since it does answer my original question. But I discovered that I actually need to bind to the window in which the button is hosted. Here is markup to do that:
<Button Background="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">My Button</Button>

Silverlight button style

I am trying out new styles with silverlight, and I created a new button skin with blend that consists of a border and a textblock. Wondered if there is a way to change the the text of the textblock when the the button's content(text) property is changed.
The binding would look like this:
<TextBlock Text="{TemplateBinding Content}"/>
The problem is when I try to set the content to something other than text:
<Button>
<Button.Content>
<Rectangle Fill="#FFB51111"/>
</Button.Content>
</Button>
In this case using the ContentPresenter would work better. It uses the same binding expression, but can display more than text. But all that is really up to you.
I don't really get what your trying to do. Normally, you include a TextBlock like that as a part of the button content.
Use a ContentPresenter rather than a TextBlock in your Template.

Resources