the content property does not change with this data trigger - wpf

I have a button and I would like to change the text of the button (content property) according to a value of other control.
I am using this code in the axml:
<Button Height="23" Name="bntMyButton" Width="75">
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=chkTest, Path=IsChecked}" Value="true">
<Setter Property="Content" Value="OK"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button>
But the button show me the text "System.Windows.Style" and not change. I try to use as value of the condition 0 and 1 instead of true and false, but I get the same result.
which is the problem?
Thanks.

You have embedded the Style as Button.Content because you forgot the Button.Style markup
<Button Height="23" Name="bntMyButton" Width="75">
<Button.Style>
<Style TargetType="Button">
....
</Style>
</Button.Style>
</Button>

Related

Custom AppBarButton from image

Step by step, I'm optimizing my xaml to create a custom AppBarButton from an image. I've gone from a complete custom xaml layout to using a few lines using styles, but I know I can simplify this one more step.
Here's what I currently have:
<Style x:Key="PrintAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="PrintAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Print"/>
</Style>
<Button Style="{StaticResource PrintAppBarButtonStyle}">
<ContentControl>
<Image Source="/Assets/AppBar/appbar_printer_dark.png"/>
</ContentControl>
</Button>
I know I can move the image source into the style definition, but I haven't been able to get this to work. After reading about the AppBarButton class, I tried to set my TargetType to AppBarButton and then set an Icon property, but was unsuccessful. Something like the following:
<Style x:Key="PrintAppBarButtonStyle" TargetType="AppBarButton" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="PrintAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Print"/>
<Setter Property="Icon">
<Setter.Value>
// here it's expecting an IconElement
</Setter.Value>
</Setter>
</Style>
<Button Style="{StaticResource PrintAppBarButtonStyle}"/>
Any tips?
The Icon property does not accept an image -- if you need to use an image, stick with the Content property. That can also be styled:
<Style x:Key="PrintAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="PrintAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Print"/>
<Setter Property="Content">
<Setter.Value>
<ContentControl>
<Image Source="/Assets/AppBar/appbar_printer_dark.png"/>
</ContentControl>
</Setter.Value>
</Setter>
</Style>
By way of explanation, note that "ContentControl.Content" is the ContentProperty, which means that the child element gets set as "Content". Ie, this:
<Button Style="{StaticResource PrintAppBarButtonStyle}">
<ContentControl>
<Image Source="/Assets/AppBar/appbar_printer_dark.png"/>
</ContentControl>
</Button>
is just shorthand for this:
<Button Style="{StaticResource PrintAppBarButtonStyle}">
<Button.Content>
<ContentControl>
<Image Source="/Assets/AppBar/appbar_printer_dark.png"/>
</ContentControl>
</Button.Content>
</Button>

How do I change a button image but still select the whole button?

I am trying to make a button in WPF that, when hovered by the mouse, lights up and gets the blue-ish selection around it. I managed the former, but by changing the button image, I apparently override the commands that highlights the button with a blue selection.
This is what I have:
<Button Command="DoSomething" Name="button">
<Button.Template>
<ControlTemplate>
<Image Height="32" Width="32" Stretch="Uniform" Name="buttonImage">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source" Value="/Project;component/Project/Bitmaps/Icon_colour.png" />
</Style>
</Image.Style>
</Image>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="false">
<Setter Property="Source" Value="/Project;component/Project/Bitmaps/Icon_grey.png" TargetName="buttonImage"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
Is there a way to get the selection back again, while keeping the icon-light-up effect?
You have replaced the default Button ControlTemplate, so all you need to do is to 'replace' the missing part(s) from the original ControlTemplate. You can find that in the Button Styles and Templates page on MSDN.
UPDATE >>>
Alternatively, you can simply add an Image into the Button.Content property:
<Button Command="{Binding DoSomething, Mode=OneWay}">
<Image Source="/Project;component/Project/Bitmaps/Icon_colour.png" />
</Button>

Trigger on an Inner/Attached property

Trigger on an Inner property
<Button BorderBrush="Black" BorderThickness="2" x:Name="TimeButton" ClickMode="Press" Click="SetTime_Click" Height="26" HorizontalAlignment="Left" Margin="15, 0, 0, 0" Style="{StaticResource ImageButtonStyle}" ToolTip="Set Time" Width="26">
<Button.Background>
<ImageBrush x:Name="TimeImageBrush" ImageSource="/YCS;component/Images/Clock.png" Stretch="Uniform" TileMode="None" />
</Button.Background>
</Button>
I need to make a trigger to set the ImageBrush in the Button.Background property to something different according to a boolean named HasHours which I can bind easily from my itemssource, any one knows how I can achieve this, I could not find any examples linking to this property....
I tried something like this
<Button.Triggers>
<DataTrigger Binding="{Binding HasHours}" Value="false">
<Setter TargetName="TimeImageBrush" Property="ImageSource" Value="/YCS;component/Images/ClockRed.png"/>
</DataTrigger>
</Button.Triggers>
but it gives me this error:
Cannot find the static member 'ImageSourceProperty' on the type 'ContentPresenter'.
Any help is much appreciated
This is perhaps not exactly an answer to your question.
First, i guess you won't be able to add a DataTrigger to the Triggers collection, since that only supports EventTriggers.
But, you could define the DataTrigger in the Button's Style. Here, instead of setting the ImageBrush's ImageSource property, simply set a new ImageBrush as Background.
<Button ...>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding HasHours}" Value="False">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/YCS;component/Images/ClockRed.png"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Put the image as Content, not as Background, since you have no content.
Put the DataTrigger in the Triggers of the Image, not of the Button.
You will have to seek for the DataContext of the Trigger :
So something like :
<Button ... >
<Image ... >
<Image.Triggers>
<DataTrigger
Binding="{Binding Path= HasHours, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Button}}}"
Value="false" >
<Setter Property="ImageSource" Value="/YCS;component/Images/ClockRed.png"/>
</DataTrigger>
</Image.Triggers>
</Image>
</Button>

Change child control (contentcontrol) property on mouseover of parent

I am new to WPF and am not able to figure out how to change the property of the child ContentControl of the Button control on mouse over. My code looks something like this:
<Button x:Name="btnAddItem" Height="25" Width="25" Margin="5,0,0,0"
Style="{DynamicResource btnStyle}" ToolTip="Add Item">
<ContentControl Content="ContentControl" Height="20" Width="20"
Template="{DynamicResource contentTemplate}" />
</Button>
Now, when in the MouseOver event of the Button, I would like to change the size of the Button as well as the size of the child ContentControl. The ContentControl actually contains a vector image for the Button. Please help.
Your Button will automatically stretch to fit the size of it's contents, so get rid of it's Height and Width properties. If you want to maintain the space between the edge of the Button and the ContentControl, use the ContentControl's Margin property.
Then, use a DataTrigger in your ContentControl's Style to change the Height/Width when the mouse is over it. Be sure you set Height/Width in your style instead of in your <ContentControl> tag, because if you set it in the tag it will take precedence over the triggered value so will never change.
<Style x:Key="MyContentControlStyle" TargetType="{x:Type ContentControl}">
<Setter Property="Height" Value="20" />
<Setter Property="Width" Value="20" />
<Setter Property="Margin" Value="5" />
<Setter Property="Content" Value="ContentControl" />
<Setter Property="Template" Value="{DynamicResource contentTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=btnAddItem, Path=IsMouseOver}" Value="True">
<Setter Property="Height" Value="20" />
<Setter Property="Width" Value="20" />
</DataTrigger >
</Style.Triggers>
</Style>
<Button x:Name="btnAddItem" Height="25" Width="25" Margin="5,0,0,0"
Style="{DynamicResource btnStyle}" ToolTip="Add Item">
<ContentControl Style="{StaticResource MyContentControlStyle}" />
</Button>
In order to achieve what I wanted, I used Rachel's advice as well as Samuel Slade's. I did it something like this:
<Button x:Name="btnEditItem" Style="{DynamicResource btnStyle}" Margin="5,0,0,0" ToolTip="Edit Item" Click="btnEditItem_Click">
<ContentControl x:Uid="ContentControl_5" Content="ContentControl" Template=" {DynamicResource contentTemplate}" Margin="2.5"/>
</Button>
And I set the height and width of the button through btnStyle via Setter property and change the height and width of the button through the triggers.
This got me working perfectly. I appreciate all your help suggestions. I am not sure if I could have reached to this conclusion as I was thinking on a different route of child controls property. Thanks again.

How do I change the image when the button is disabled?

I'm trying to show a different image when the button is disabled; I thought it would be easy with triggers.
However, I have not been able to get the image source to switch to the disabled image when the button is disabled. I've tried setting triggers on both the image and button. What is wrong with what I have below? How can I change the image source when the button is enabled/disabled?
<Button
x:Name="btnName"
Command="{Binding Path=Operation}"
CommandParameter="{x:Static vm:Ops.OpA}">
<Button.Content>
<StackPanel>
<Image
Width="24"
Height="24"
RenderOptions.BitmapScalingMode="NearestNeighbor"
SnapsToDevicePixels="True"
Source="/MyAssembly;component/images/enabled.png">
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=btnName, Path=Button.IsEnabled}" Value="False">
<Setter Property="Image.Source" Value="/MyAssembly;component/images/disabled.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</Button.Content>
</Button>
Yeah this one pops up quite a bit.
Any property that's explicitly set in the object's declaration can't be changed in a style. So because you've set the image's Source property in the declaration of the image, the style's Setter won't touch it.
Try this instead:
<Image
Width="24"
Height="24"
RenderOptions.BitmapScalingMode="NearestNeighbor"
SnapsToDevicePixels="True"
>
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source"
Value="/MyAssembly;component/images/enabled.png" />
<Style.Triggers>
... your trigger and setter ...
</Style.Triggers>
</Style>
</Image.Style>
</Image>

Resources