wpf button trigger doesnt work as it should - wpf

I have a simple button. I want to switch it's template(or style ...)when it is being preesed.
I want to change from this
<DataTemplate>
<Button Click="Button_Click"
DataContext="{Binding}"
Height="65" Width="79"
Background="Black"
Content="{Binding Path=CardWasFounded}"/>
</DataTemplate>
to this :
<DataTemplate>
<Button Click="Button_Click"
DataContext="{Binding}"
Height="65" Width="79"
Background="{Binding Path=ButtonColor}"
Content="{Binding Path=CardWasFounded}"/>
</DataTemplate>
EDIT
After i have done
<DataTemplate>
<Button Name="btn"
Click="Button_Click"
DataContext="{Binding}"
Height="65" Width="79"
Background="Black"/>
<DataTemplate.Triggers>
<Trigger SourceName="btn" Property="IsMouseCaptured" Value="True" >
<Setter TargetName="btn" Property="Background" Value="Green"/>
<!--"{Binding Path=ButtonColor}"-->
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
It's still doesn't work I think it's because the .net default or something when the mouse is over the button its get's the blue defult color insted of my green or my binding ...
My goal its when its clicked to hook up a binding to color and a storyboard
can someone help me achive it ?

You can achieve this effect with a trigger. You could set a trigger that changes the Background property to your desired value when the button's IsPressed property (or some similar property) equals true.
For more information, take a look at:
http://en.csharp-online.net/WPF_Styles_and_Control_Templates%E2%80%94Property_Triggers

Related

Button foreground doesn't change when content is StackPanel

I have a button style defined where the template has a ContentPresenter with a name of "contentPresenter". It then has a trigger set up like this:
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383" />
</Trigger>
</ControlTemplate.Triggers>
This trigger simply changes the foreground color of a button to gray when the button is disabled. However, I have one button in my application which does not have simple text as its content. The button looks like this:
<Button Grid.Column="3" Grid.Row="3" Grid.ColumnSpan="2"
Margin="120 20 30 10"
Command="{Binding SomeCommand}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding MyImage}" Margin="0 0 2 0"
Visibility="{Binding ShowMyImage, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<TextBlock Text="{Binding ButtonText}" />
</StackPanel>
</Button>
The foreground of this button is always the same whether the button is disabled or not. I'm thinking it's because the text for the button is in a textblock within the stackpanel in the content presenter, but I don't know how to get the foreground color changes to be applied to the inner textblock.
I tried changing the Property in the trigger to use "TextBlock.Foreground" instead of "TextElement.Foreground". I also tried binding the Foreground of the inner textblock to the foreground color of the closest ancestor of type FrameworkElement like this:
<TextBlock Text="{Binding ButtonText}" Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(FrameworkElement.Foreground)}" />
None of this worked. What do I need to do to get the foreground color to apply to the TextBlock inside the StackPanel?
Your trigger should be in the Style, and should be setting Foreground on the Button itself, rather than on the ContentPresenter. Then it'll Just Work, with a custom template or with the default template. No need for any extra bindings.
<Style TargetType="Button" x:Key="MyButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="Beige" BorderBrush="Black" BorderThickness="1" Padding="6,2">
<ContentPresenter
/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#FF838383" />
</Trigger>
</Style.Triggers>
</Style>
Usage:
<Button
IsEnabled="False"
Style="{StaticResource MyButtonStyle}"
>
<StackPanel>
<TextBlock
>Blah Blah</TextBlock>
<Button>X</Button>
</StackPanel>
</Button>
<Button Style="{StaticResource MyButtonStyle}" IsEnabled="False">Testing</Button>
Screenshot (never mind my ugly template):

How to click TextBox (or Label) to toggle checkbox

I have a WPF app with the follow XAML
<CheckBox IsChecked="{Binding IsTime}" />
<TextBlock Text="Time" />
What I'd like is if the user clicks the textbox, it will toggle the CheckBox. In the same way we can use label and a checkbox in MVC.NET (well, HTML)
I could do this with events in the code behind but I'm using MVVM and as such, don't want to use those events.
The difference between my question and Change a Label's behavior to support toggling by click in WPF is that I'm already binding my CheckBox to something...
I hope this effort provides a clearer idea on what I'm trying to do
<CheckBox IsChecked="{Binding IsTime}" x:Name="Checky" />
<TextBlock Text="Time">
<TextBlock.Style>
<Style>
<Style.Triggers>
<Trigger Property="TextBlock.MouseDown" Value="True">
<Setter TargetName="Checky" Property="IsChecked" Value=Not IsTime> //WHAT TO DO HERE
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
You can put the TextBox and other controls inside the CheckBox. This way clicking the TextBox will also toggle the CheckBox. Here's an example with multiple items inside the CheckBox, but you could of course have only the TextBox inside it.
<CheckBox Padding="2" IsChecked="{Binding IsTime}">
<StackPanel Orientation="Horizontal">
<Image Width="24" Height="24" Source="someimage"/>
<TextBlock Text="Time"/>
</StackPanel>
</CheckBox>
Use the code in the link you have provided and bind IsChecked to the same property:
<StackPanel>
<CheckBox x:Name="checkbox" IsChecked="{Binding IsTime}"/>
<CheckBox IsChecked="{Binding IsTime}" Content="Hello">
<CheckBox.Template>
<ControlTemplate TargetType="CheckBox">
<ContentPresenter/>
</ControlTemplate>
</CheckBox.Template>
</CheckBox>
</StackPanel>
You know that you have a Content property on the CheckBox which can be templated to achieve the desired effect without having to use multiple CheckBox-es.

ListBox item template depends on item values

In WPF, MVVC applicaiton I have quite normal listbox:
<ListBox ItemsSource="{Binding Friends}">
</ListBox>
Then each item of list uses following datatemplate:
<DataTemplate DataType="{x:Type model:Friend}">
<Border BorderThickness="1" BorderBrush="Gray" Padding="3" Name="border" Margin="3">
<StackPanel Grid.Row="1" Grid.Column="2" Orientation="Horizontal">
<TextBlock Name="DescriptionDTDataType" Text="{Binding Path=ConnectedUserID}" />
<TextBlock Name="StatusTitle" Margin="8,0,4,0">Status:</TextBlock>
<TextBlock Name="Status" Text="{Binding Path=Approved}" />
<Button Content="Approve" Command="{x:Static inf:Commands.ApproveUserConnection}" CommandParameter="{Binding}"></Button>
<Button Content="Disapprove" Command="{x:Static inf:Commands.DisapproveUserConnection}" CommandParameter="{Binding}"></Button>
</StackPanel>
</Border>
</DataTemplate>
The question is... I want to hide one of the buttons on the basic of Friend.Approved property. For example if Friend.Approved has value "approved" I want to hide button Approved and show only button Dissaprove. On the other hand if Friend.Approved has value "disapproved" then I want opposite. How to achieve this?
Thank you.
Beside creating a IValueConverter there is a pure XAML solution using DataTriggers
Just add this to your DataTemplate:
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Approved}" Value="approved" >
<Setter TargetName="Approve" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding Approved}" Value="disapproved" >
<Setter TargetName="Disapprove" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
And name your buttons:
<Button Name="Approve" Content="Approve" ...></Button>
<Button Name="Disapprove" Content="Disapprove" ...></Button>
However if you want to reuse this hiding logic in multiple places in multiple DataTemplates its better to write the Approved text to Visibility converter.
Bind the Buttons Visibility property to Approved and use a value converter to convert Approved to a Visibility value.

wpf binding to element

Well i guess it's easy my scenario is having 2 elements:
ListBox and Button:
<ListBox Name="BannedItemsListBox"
Margin="5"
MinWidth="100"
MaxWidth="100" " Height="
204" ItemsSource="{Binding Path=BannedItems, Mode=TwoWay}"></ListBox>
<Button Name="RemoveBannedItemsButton"
Margin="5"
MinWidth="65"
Height="22"
Click="RemoveBannedItemButton_Click">Remove</Button>
I want to bind the IsEnabled property button to be true only if Item from ListBox is selected (focused) in XAML
I tried
IsEnabled="{Binding ElementName=BannedSourcesListBox, Path=TouchesDirectlyOver.Count}"
but no go.
What does the selection have to do with the Touches? (Also the ElementName is off)
I would try this:
IsEnabled="{Binding SelectedItems.Count, ElementName=BannedItemsListBox}"
Explanation: Basically the binding system tries to convert the input to the property at hand, a boolean, so when it gets an integer, 0 will be converter to false, anything higher to true. So the Button will be enabled if one or more items are selected.
<Button Content="Button"
Height="23"
HorizontalAlignment="Left"
Margin="138,12,0,0"
Name="button1"
VerticalAlignment="Top"
Width="75"
Click="button1_Click">
<Button.Style>
<Style>
<Setter Property="Button.IsEnabled"
Value="True" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=lstTest , Path=SelectedItem}"
Value="{x:Null}">
<Setter Property="Button.IsEnabled"
Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

XAML controls binding with another controls which are in datatemplate !

i have the following datatemplate in xaml and here i have textbox in datatemplate and button in normal XAML, what i really want is that i want to keep button be disabled until person enters something in textbox ? but its not working i have tried the follwing code
Please look into it and help me as well ! or is there any other way to do this let me know !
<UserControl.Resources>
<DataTemplate x:Key="dataTemplateParameter">
<StackPanel Width="170" Height="Auto" Margin="5">
<TextBlock Width="160" TextAlignment="Left" HorizontalAlignment="Left" Height="22" Text="{Binding Path=ParameterName, Mode=TwoWay}"/>
<TextBox x:Name="txtboxParameter" Width="160" Height="22" HorizontalAlignment="Left" Text="{Binding Path=ParameterValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</DataTemplate>
<Button Grid.Row="6" Name="SearchSourceParamBtn" Content="Search" VerticalAlignment="Bottom" Margin="12,5,92,0" Height="20" Visibility="{Binding SearchSourceBtnVisibility}" Command="{Binding SearchCommand}">
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text,x:ElementName=txtboxParameter}" Value="">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Thanks
nallskarthi
You can achieve this by
1) binding button to RelayCommand. Then,
2) Validate the "ParameterValue" in command's CanExecute delegate.
Edit:
The better way is to have the ParameterValue in ViewModel, but for some reason you won't do that. Then, create a static ChangeNotifyable property in VM, using this property do the validation in CanExecute delegate.
Pls Validate the "ParameterValue" in the CanExecute delegate of Command object.

Resources