Fill button into a datagrid cell - wpf

I have a data grid and for the column HCode I have/need buttons, but the property Code can be null/empty in which case the Button will not be visible.
I'd like to know if there are options or defining a mouse-click handler for the cell is the way to go.
Below is the DataGridTemplate defining the column
<DataGridTemplateColumn Header="HCode" MinWidth="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{Binding Code}"
Style="{StaticResource BStyle}"
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=TextBlock}, Path=Background}"
Click="ButtonBase_OnClick"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center"
/>
<!--Visibility="{qc:Binding '$P != null && $P.Length > 0 ? Visibility.Visible : Visibility.Collapsed', P={Binding Code}}"-->
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
Below is the style that is used
<Style x:Key="BStyle"
TargetType="{x:Type Button}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30*"></RowDefinition>
</Grid.RowDefinitions>
<ContentPresenter Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
RecognizesAccessKey="True" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground"
Value="Blue" />
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Foreground"
Value="Red" />
</Trigger>
</Style.Triggers>
</Style>

You could define two DataTriggers. Try this:
<Button Content="{Binding Code}"
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=TextBlock}, Path=Background}"
Click="ButtonBase_OnClick"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource BStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding Code}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding Code.Length}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Or:
<DataTrigger Binding="{Binding Code.Length, FallbackValue=0}" Value="0">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>

Related

WPF mouse hover canvas

i could not find answers on SO anywhere - how do i make hover effect for each "item"
i want that when i hover over canvas (data template, positioned inside grid) to change color on both rectangles that are inside canvas - only place where IsMouseOver works is where i set ContentPresenter, and there i can change size of Grid, and thats all. I cannot get IsMouseOver on canvas to change color of rectangles inside. Anyhow, i am just begginer, so, i know something is wrong, ContentPresenter maybe is the one that takes style trigger, i just do not know how to fix this.
<Border Background="#1C222E">
<Viewbox Grid.Column="0" Grid.Row="0" Name="SeatsBox">
<Viewbox.RenderTransform>
<ScaleTransform ScaleX="1.0" ScaleY="1.0"/>
</Viewbox.RenderTransform>
<ItemsControl ItemsSource="{Binding Seats}" Name="SeatsItems">
<ItemsControl.RenderTransform>
<TranslateTransform X="0" Y="0" />
</ItemsControl.RenderTransform>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid local:GridHelpers.RowCount="{Binding RowCount}" HorizontalAlignment="Center" VerticalAlignment="Center" local:GridHelpers.ColumnCount="{Binding ColumnCount}" ShowGridLines="False" Background="#1C222E" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding RowEx}" />
<Setter Property="Grid.Column" Value="{Binding ColumnEx}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Width" Value="60"/>
</Trigger>
</Style.Triggers>
<Style.Resources>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Width" Value="200" />
<Setter Property="Fill" Value="Blue" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=IsMouseOver}" Value="True">
<Setter Property="Fill" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Style.Resources>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas Width="30" Height="30" Margin="4" Background="Transparent" Tag="{Binding ID}">
<Rectangle Name="RecTop" Canvas.Top="4" Canvas.Left="1" Width="28" Height="18" Fill="#5D606D" Stroke="#5D606D" RadiusX="2" RadiusY="2"></Rectangle>
<Rectangle Name="RecBot" Canvas.Top="23" Canvas.Left="1" Width="28" Height="7" Fill="#5D606D" Stroke="#5D606D" RadiusX="2" RadiusY="2"></Rectangle>
<!-- <TextBlock Text="{Binding Path=Column}" TextWrapping="Wrap" TextAlignment="Center" VerticalAlignment="Center" /> -->
</Canvas>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Taken">
<Setter TargetName="RecTop" Property="Stroke" Value="#2E3441" />
<Setter TargetName="RecTop" Property="Fill" Value="#2E3441" />
<Setter TargetName="RecBot" Property="Stroke" Value="#2E3441" />
<Setter TargetName="RecBot" Property="Fill" Value="#2E3441" />
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="Reserved">
<Setter TargetName="RecTop" Property="Stroke" Value="#5D606D" />
<Setter TargetName="RecBot" Property="Stroke" Value="#5D606D" />
<Setter TargetName="RecTop" Property="Fill" Value="Transparent" />
<Setter TargetName="RecBot" Property="Fill" Value="Transparent" />
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="Broken">
<Setter TargetName="RecTop" Property="Stroke" Value="#1885FF" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Viewbox>
</Border>
You've actually already done it properly, the problem is that you're setting Fill explicitly in the Rectangle declarations:
<Rectangle ... Fill="#5D606D" ...></Rectangle>
<Rectangle ... Fill="#5D606D" ...></Rectangle>
Those fields have precedence over what you've set in your style, remove them and your code works fine.

Check my ListView progress-bar cell backgroung color based on property

So i have this cell Progress-Bar inside my ListView.Resources:
<DataTemplate x:Key="MyDataTemplate">
<Grid Margin="-6,0,0,0" Height="20.5" Width="80">
<ProgressBar Name="progressBarColumn"
Maximum="100"
Value="{Binding Progress, UpdateSourceTrigger=PropertyChanged}"
Width="{Binding Path=Width, ElementName=ProgressCell}"
Background="{Binding Path=IsCkecked}"
Margin="0,0,0,0"
Style="{StaticResource CustomProgressBar}" />
<TextBlock Text="{Binding Path=Value, ElementName=progressBarColumn, StringFormat={}{0:N1}%}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="{DynamicResource ProgressBarForegroundColor}"
FontFamily="{DynamicResource ProgressBarFontFamily}"
FontSize="{DynamicResource ProgressBarFontSize}"
Margin="{DynamicResource ProgressBarMargin}"/>
</Grid>
</DataTemplate>
And my style:
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderBrush="{DynamicResource ProgressBorderBrushColor}" BorderThickness="0" Background="{DynamicResource ProgressBackgroundColor}" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="{DynamicResource ProgressBarFillColor}"/>
<Style.Triggers>
<DataTrigger Value="100" Binding="{Binding Path=Value, RelativeSource={RelativeSource AncestorType=ProgressBar}}">
<Setter Property="Fill" Value="{DynamicResource ProgressBarFillCompleteColor}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now inside my ListView each binding object has this bool property IsChecked which is another CheckBox cell and when this CheckBox is Unchecked my IsChecked property is false and in this case i wan to change my Progress-Bar Background color.
So this is what i have try and add into my Progress-Bar style (not effect at all on my Progress-Bar Background color...):
<DataTrigger Value="False" Binding="{Binding Path=IsChecked, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=CheckBox}}">
<Setter Property="Fill" Value="Red"/>
</DataTrigger>
EDIT:
My CheckBox is already bind into my property:
IsChecked="{Binding Path=IsChecked}"
...
<DataTrigger Value="True" Binding="{Binding Path=IsChecked}">
<Setter Property="Fill" Value="Red"/>
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding Path=IsChecked}">
<Setter Property="Fill" Value="Yellow"/>
</DataTrigger>
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged();
}
}
after a little bit of work here is the solution:
<Style x:Key="CustomProgressBar" TargetType="ProgressBar">
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsChecked}">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Value="False" Binding="{Binding Path=IsChecked}">
<Setter Property="Background" Value="Yellow"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="ProgressBar">
<Border BorderBrush="{DynamicResource ProgressBorderBrushColor}" BorderThickness="0" Background="{DynamicResource ProgressBackgroundColor}" CornerRadius="0" Padding="0">
<Grid x:Name="PART_Track">
<Rectangle x:Name="PART_Indicator" HorizontalAlignment="Left">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="{Binding}"/>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Set property of ViewModel using setter within some Trigger

I tried to google but all problems had related heading but problem context different. My problem is that I have a DataTrigger which gets triggered when certain property has a certain value i-e IsDockPanelVisible has true/false (different triggers for each value) in my case. Now when it gets triggered, it should set the value of Width - a property defined in ViewModel. Here is my specific code:
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="mainWindowViewModel.Width" Value="Auto">
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="mainWindowViewModel.Width" Value="7*"></Setter>
<Setter Property="MinWidth">
<Setter.Value>
<MultiBinding Converter="{StaticResource StringSumtoIntConvert}">
<Binding ElementName="cdLblNotificationsHeader" Path="MinWidth"/>
<Binding ElementName="cdBtnNotificationsClose" Path="ActualWidth"/>
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
Here is complete code:
<Window x:Class="EmbroidaryManagementSystem_V2._0.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:EmbroidaryManagementSystem_V2._0.View"
xmlns:adf="clr-namespace:EmbroidaryManagementSystem_V2"
xmlns:collectionVM="clr-namespace:EmbroidaryManagementSystem_V2._0.ViewModel.CollectionsViewModel"
xmlns:helperClasses="clr-namespace:EmbroidaryManagementSystem_V2._0.HelperClasses"
xmlns:mainWindowVM="clr-namespace:EmbroidaryManagementSystem_V2._0.ViewModel.UIViewModel"
mc:Ignorable="d"
Title="Khalil Embroidery Management System" Height="655.512" Width="1135.159" FontSize="24"
WindowStartupLocation="CenterScreen" MinWidth="200" MinHeight="300"
Icon="/EmbroidaryManagementSystem V2.0;component/Images/KhalilEmbroideryLogonobackgrnd2.png"
>
<Window.DataContext>
<!--<collectionVM:ClientCollectionVM/>-->
<mainWindowVM:MainWindowViewModel/>
</Window.DataContext>
<Window.Resources>
<helperClasses:StringSumtoIntConverter x:Key="StringSumtoIntConvert"/>
<ControlTemplate x:Key="DockedPanelButtonTemplate" TargetType="{x:Type Button}">
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Black"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="DockedPanelButton" TargetType="Button">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="90"/>
</Setter.Value>
</Setter>
<!--<Setter Property="Template" Value="{StaticResource DockedPanelButtonTemplate}"/>-->
<Setter x:Name="border" Property="BorderBrush" Value="DodgerBlue"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Aquamarine"/>
<Setter Property="Background" Value="Yellow"/>
</Trigger>
</Style.Triggers>
</Style>
<!--<mainWindowVM:MainWindowViewModel x:Key="WindowViewModel"/>-->
<Style x:Key="OnIsDockPanelVisibleChangedGridBehaviour" TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="OnIsDockPanelVisibleChangedPanelColumnBehaviour" TargetType="ColumnDefinition">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="mainWindowViewModel.Width" Value="Auto">
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="mainWindowViewModel.Width" Value="7*"></Setter>
<Setter Property="MinWidth">
<Setter.Value>
<MultiBinding Converter="{StaticResource StringSumtoIntConvert}">
<Binding ElementName="cdLblNotificationsHeader" Path="MinWidth"/>
<Binding ElementName="cdBtnNotificationsClose" Path="ActualWidth"/>
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="OnIsDockPanelVisibleChangedButtonBehaviour" TargetType="Button"
BasedOn="{StaticResource DockedPanelButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="OnIsDockPanelVisibleChangedGridSplitterBehaviour" TargetType="GridSplitter">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsDockPanelVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
<SolidColorBrush x:Key="TransparentBackground">
Transparent
</SolidColorBrush>
<Style x:Key="LeftDockedPanelButton" TargetType="Button" BasedOn="{StaticResource OnIsDockPanelVisibleChangedButtonBehaviour}">
<Setter Property="BorderThickness" Value="0,0,0,15"/>
</Style>
<Style x:Key="RightDockedPanelButton" TargetType="Button" BasedOn="{StaticResource OnIsDockPanelVisibleChangedButtonBehaviour}">
<Setter Property="BorderThickness" Value="0,8,0,0"/>
</Style>
<BitmapImage x:Key="LogoImage" UriSource="/Images/KhalilEmbroideryLogonobackgrnd2.png"/>
</Window.Resources>
<!--<ScrollViewer HorizontalScrollBarVisibility="Auto">-->
<Grid x:Name="mainGrid" Background="#FFD6DBE9">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition MinHeight="103"/>
</Grid.RowDefinitions>
<Menu Height="18" VerticalAlignment="Top" Grid.Row="0" Margin="0,0,0,0">
<MenuItem Header="_Exit">
<MenuItem Header="Exit"/>
</MenuItem>
<MenuItem Header="_View">
<MenuItem Header="Notifications" Command="{Binding ShowDockPanelCommand}"/>
</MenuItem>
<MenuItem Header="Add _New">
<MenuItem Header="Employee"/>
<MenuItem Header="Employee Salary"/>
</MenuItem>
<MenuItem Header="_About">
<MenuItem Header="About us"/>
</MenuItem>
</Menu>
<ScrollViewer HorizontalScrollBarVisibility="Auto" Grid.Row="1">
<Grid x:Name="innerContentGrid" MinHeight="500" MinWidth="600">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20*" MinWidth="{Binding MinWidth, ElementName=tabDataEntities}"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Style="{StaticResource OnIsDockPanelVisibleChangedPanelColumnBehaviour}" Width="{Binding }"/>
</Grid.ColumnDefinitions>
<GridSplitter x:Name="gridSplitter" Grid.Column="1" HorizontalAlignment="Center"
Width="3" Margin="0,10,0,0" Background="#FF657695"
Style="{StaticResource OnIsDockPanelVisibleChangedGridSplitterBehaviour}"/>
<Grid x:Name="gridNotificationsHeader" Grid.Column="2" Background="#FF657695" Margin="0,10,0,0"
Height="30" VerticalAlignment="Top" Style="{StaticResource OnIsDockPanelVisibleChangedGridBehaviour}">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="cdLblNotificationsHeader"
MinWidth="{Binding Width, ElementName=lblNotificationsHeader}"/>
<ColumnDefinition x:Name="cdBtnNotificationsClose" Width="Auto"/>
</Grid.ColumnDefinitions>
<Label x:Name="lblNotificationsHeader" Content="Notifications" VerticalAlignment="Top"
FontSize="14.667" Height="29" Foreground="#FFEBF0EE" HorizontalAlignment="Left" Width="92"/>
<Button x:Name="btnNotificationsClose" Content="X"
Margin="0,5,8,0" VerticalAlignment="Top" Width="20" FontFamily="Verdana" HorizontalAlignment="Right"
Background="Transparent" FontSize="13.333" Foreground="Black" Grid.Column="1"
Command="{Binding HideDockPanelCommand}"/>
</Grid>
<TabControl Grid.Column="0" x:Name="tabDataEntities" Margin="0,10,5,0" FontSize="12"
MinWidth="{Binding ElementName=TabItemOne, Path=ActualWidth}">
<TabItem x:Name="TabItemOne">
<TabItem.Header>Tab Item</TabItem.Header>
<Grid Background="#FFE5E5E5" Margin="0,0,0,0"/>
</TabItem>
<TabItem Header="TabItem">
<Grid Background="#FFE5E5E5"/>
</TabItem>
</TabControl>
<Button x:Name="btnShowNotificationsPanel" Content="Notifications" Grid.Column="2"
Margin="0,12,-0,0" VerticalAlignment="Top" Style="{StaticResource RightDockedPanelButton}" Background="Transparent"
FontSize="12" Height="Auto" HorizontalAlignment="Right" Width="Auto"
Command="{Binding ShowDockPanelCommand}"/>
</Grid>
</ScrollViewer>
</Grid>
Width is property in my ViewModel and not FrameworkElement.Width. However, it has the same double type. ViewModel class is MainWindowViewModel and its object in XAML is mainWindowVM.
You can not set view model properties with a setter of your view.
Have a look here: Setter.Property Property.
It states that you can only uses a DependencyProperty as the value for the setter (Besides, you cannot specify a binding expression there, just a string value).
<object Property="DependencyProperty" .../>
Suggestion:
If IsDockPanelVisible is a property inside your view model, you could react to change events there in your view model, either by subscribing to INotifyPropertyChanged of this property or by calling a method in the setter of IsDockPanelVisible.
You could then set another property in your view model which is bound to the view and then achieve your desired result.

WPF Set element property on Enter key pressed

i have defined custom style for my Label like code below:
<Style x:Key="GridLabelStyle" TargetType="{x:Type Label}">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Foreground" Value="Black" />
<Setter Property="Height" Value="30"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70*"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tag, Mode=OneWay}"/>
<Border Grid.Column="1" Name="grayborder" BorderBrush="#B2E8E4E4" BorderThickness="1" CornerRadius="2" Background="White">
<Grid>
<TextBlock Name="textblock" VerticalAlignment="Center" Margin="3"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content, Mode=TwoWay}" />
<TextBox Name="textbox" VerticalContentAlignment="Center" BorderThickness="0"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</TextBox>
</Grid>
</Border>
<ToggleButton Grid.Column="2" Name="Edit" Margin="5,0,0,0" ContentTemplate="{StaticResource editicon}" Style="{DynamicResource NoStyleToggleButton}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="Edit" Property="IsChecked" Value="False">
<Setter TargetName="textblock" Property="Visibility" Value="Visible"/>
<Setter TargetName="textbox" Property="Visibility" Value="Collapsed"/>
<!--<Setter TargetName="Edit" Property="Command" Value="{Binding UpdateElementCommand}"/>-->
</Trigger>
<Trigger SourceName="Edit" Property="IsChecked" Value="True">
<Setter TargetName="textblock" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="textbox" Property="Visibility" Value="Visible"/>
<Setter TargetName="Edit" Property="ContentTemplate" Value="{StaticResource saveicon}"/>
<Setter TargetName="grayborder" Property="BorderBrush" Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The main thing i want to do is to handle trigger for key press (Enter) on element name "textbox" and set property on element name "edit" to IsChecked=False.
I am using .NET 3.5 and MVVM.
Is it possible to do it without any C# code behind?
Regards

How to trap button click event inside listbox item template

I have listbox with textbox inside to display list items. I want to have editable textbox , So I put button inside listbox for selected textbox. I want to trigger button click event for that listbox but I couldn't. Here is my code:
<ListBox HorizontalAlignment="Left" Name="ListTwo" Height="auto" Margin="134.53,15.934,0,0" VerticalAlignment="Top" Width="202.308" ItemsSource="{Binding . ,Source=CollectionUrl,BindsDirectlyToSource=True}" BorderThickness="0" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<RadioButton>
<TextBox Name="TextBoxList" Text="{Binding Path=urlString, Mode=TwoWay}" Width="150">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="IsReadOnly" Value="False" />
<Setter Property="BorderThickness" Value="0.5"/>
</Trigger>
<Trigger Property="IsFocused" Value="False">
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="BorderThickness" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</RadioButton>
<Button Content="Save" Grid.Column="1" Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}}" Click="Button_Click_2">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=TextBoxList, Path=IsFocused}" Value="True">
<Setter Property="Visibility" Value="Visible" />
<Setter Property="ClickMode" Value="Press"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Anyone knows how can I trap click event of button?
Did you try adding an event for Button in the ListBox. This will capture the event.
Button.Click="OnClick"
So like this:
<ListBox HorizontalAlignment="Left" Name="ListTwo" Height="auto" Margin="134.53,15.934,0,0" VerticalAlignment="Top" Width="202.308" ItemsSource="{Binding . ,Source=CollectionUrl,BindsDirectlyToSource=True}" BorderThickness="0" Button.Click="OnClick">
Then your event:
private void OnClick(object sender, RoutedEventArgs e)
{
var originalSource = e.OriginalSource;
// Do your work here
}
However, you have a second problem. Your button style is preventing your event from firing. It works without the style but doesn't fire with the style. Change the style to be on ListBoxItem.IsSelected. Then make it so if you select a TextBox the ListBoxItem is selected.
<ListBox HorizontalAlignment="Left" Name="ListTwo" Height="auto" Margin="134.53,15.934,0,0" VerticalAlignment="Top" Width="202.308" ItemsSource="{Binding . ,Source=CollectionUrl,BindsDirectlyToSource=True}" BorderThickness="0" Button.Click="OnClick">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<RadioButton>
<TextBox Name="TextBoxList" Text="{Binding Path=urlString, Mode=TwoWay}" Width="150">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="IsReadOnly" Value="False" />
<Setter Property="BorderThickness" Value="0.5"/>
</Trigger>
<Trigger Property="IsFocused" Value="False">
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="BorderThickness" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</RadioButton>
<Button Content="Save" Grid.Column="1">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
<Setter Property="Visibility" Value="Visible" />
<Setter Property="ClickMode" Value="Press"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource Self}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(ListBoxItem.IsSelected)">
<DiscreteBooleanKeyFrame KeyTime="0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Hope that helps.
You have several options to do it but I'll just give you the two best ones without using third party frameworks.
First is through System.Windows.Interactions and put it inside the TextBox. This will be handled in your ViewModel
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click" >
<i:InvokeCommandAction Command="{Binding ClickCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Second is through using EventSetter, this will be handled behind the View
<Style TargetType="ListBoxItem">
<EventSetter Event="MouseDoubleClick" Handler="TextBoxClick"/>
</Style>

Resources