WPF Set element property on Enter key pressed - wpf

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

Related

C# WPF Use multi image source ControlTemplate with Button.Tag

I have a problem on the using ControlTemplate in Button. I would like to create a button with image and text. When mouse over the button, the image change. I use the Button.Tag to pass the image source. But I need to pass two image sources. Is it possible to create a list of image source in Button.Tag and select in the ControlTemplate? Thanks you.
<Style x:Key="myBtnStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<StackPanel Orientation="Horizontal">
<Image x:Name="myImg" Source="{TemplateBinding Tag[0]}" HorizontalAlignment="Left"/>
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Left"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="myImg" Property="Source" Value="{TemplateBinding Tag[1]}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Content="Click" Style="{StaticResource myBtnStyle}">
<Button.Tag>
<ImageSource>/img/usb_white.png</ImageSource>
<ImageSource>/img/usb_gray.png</ImageSource>
</Button.Tag>
</Button>
You could set the Tag property to an ImageSource[] using the <x:Array> element:
<Button Content="Click" Style="{StaticResource myBtnStyle}">
<Button.Tag>
<x:Array Type="ImageSource">
<BitmapImage UriSource="Images/Buldingimage2.jpeg" />
<BitmapImage UriSource="Images/words.jpg" />
</x:Array>
</Button.Tag>
</Button>
You also need to replace the TemplateBindings in the template with bindings to TemplatedParent:
<Style x:Key="myBtnStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<StackPanel Orientation="Horizontal">
<Image x:Name="myImg" Source="{Binding Tag[0], RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Left"/>
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Left"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="myImg" Property="Source" Value="{Binding Tag[1], RelativeSource={RelativeSource TemplatedParent}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="btn_img" TargetType="Button">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Margin" Value="3"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="FontWeight" Value="Medium"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Background" Value="WhiteSmoke"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="2 0 0 0">
</ContentPresenter>
<ContentControl HorizontalAlignment="Left" Grid.Column="1" Content="{TemplateBinding Tag}" Margin="0 0 2 0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource b_blue}"/>
<Setter Property="Foreground" Value="#fff"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Gray"/>
<Setter Property="Foreground" Value="#fff"/>
</Trigger>
</Style.Triggers>
</Style>

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>

Fill button into a datagrid cell

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>

How to align the first TabItem with the left border of its TabControl?

I'm working on a custom TabControl for my C#-WPF-application. Basically, everything I want works just fine. Except for one litte thing that really annoys me: The first TabItem of the TabControl is indentet 2 pixels and therefore won't align with the left border of the TabControl. Unfortunately I can't yet post pictures, so I hope you guys get what I mean...
So, is there any possibility to get the first TabItem aligned with its TabControl? Maybe by somehow setting its position?
Here's the entire XAML-code:
<UserControl x:Class="DocumentationOfXmlInterfaces.CentralTabControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<TabControl
Name="MyTabcontrol"
BorderBrush="Navy"
BorderThickness="2"
ItemsSource="{Binding}"
SelectionChanged="MyTabcontrol_SelectionChanged"
>
<TabControl.Resources>
<Style TargetType="TabPanel">
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
ClipToBounds="True"
>
<Border
x:Name="MyBorder"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="Navy"
BorderThickness="1"
>
<DockPanel
Name="MyDockpanel_Content"
>
<ContentPresenter
x:Name="MyContentPresenter"
HorizontalAlignment="Center"
Content="{TemplateBinding Content}"
/>
</DockPanel>
</Border>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsSelected}"
Value="False"
>
<Setter
TargetName="MyBorder"
Property="Border.BorderBrush"
Value="RoyalBlue"
/>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter
TargetName="MyBorder"
Property="Border.BorderBrush"
Value="White"
/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="TabHeader" DataType="TabItem">
<DockPanel>
<Button
Name="MyButton_CloseTab"
DockPanel.Dock="Right"
Margin="10,1,1,0"
Click="MyButton_Click"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Name}"
>
<Image Name="MyImage_Button" Source="Icons/Close.png" Height="12" Width="12"/>
</Button>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type TabItem}}, Path=Header}"/>
</DockPanel>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsSelected}"
Value="False"
>
<Setter
TargetName="MyButton_CloseTab"
Property="Visibility"
Value="Hidden"
/>
<Setter
TargetName="MyImage_Button"
Property="Source"
Value="Icons/Close2.png"
/>
<Setter
TargetName="MyImage_Button"
Property="Height"
Value="12"
/>
<Setter
TargetName="MyImage_Button"
Property="Width"
Value="12"
/>
</DataTrigger>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsMouseOver}"
Value="True"
>
<Setter
TargetName="MyButton_CloseTab"
Property="Visibility"
Value="Visible"
/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<Style TargetType="TabItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TabItem">
<Border
x:Name="MyBorder"
BorderBrush="Navy"
BorderThickness="1,1,1,0"
>
<Grid Name="Panel">
<ContentPresenter
x:Name="ContentSite"
ContentSource="Header"
Margin="5,0,0,0"
/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Panel" Property="Background" Value="Navy"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Panel" Property="Background" Value="RoyalBlue"/>
<Setter TargetName="MyBorder" Property="BorderBrush" Value="RoyalBlue"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MyBorder" Property="BorderBrush" Value="Navy"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="Grid">
<Setter Property="VerticalAlignment" Value="Stretch"></Setter>
<Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
</Style>
</TabControl.Resources>
</TabControl>
I'd really appreciate your help!
Thanks! :)
Your problem here is that the headers TabPanel inside the TabControl template has its Margin set explicitly, and your Style won't be able to override it.
You may need to modify the whole TabControl's Template to change the value of that Margin.
So maybe it'd be easier to just do the negative margin trick :P
In the same mindset as this answer (Change GroupBox Header location), you could have a negative left margin on your tab item. Like this: Margin="-2,0,0,0"

How to make control in controltemplate visible only when treeview has items bound to it

So I have this control template, and I want the signalnamepanel (just a label for time, and i'm going to add an x axis beside it) to only become visible when items are bound to the Treeview.
Otherwise it will look weird because the namepanel will be floating there by itself. I am guessing I need to use triggers of some kind, but I'm not sure what I would trigger off of.
<Style x:Key="{x:Type TreeView}" TargetType="TreeView">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeView">
<ScrollViewer
Focusable="False"
CanContentScroll="False"
Padding="4">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="{Binding ElementName=graph_viewer, Path=signal_graph_window_width, Mode=OneWay}" />
</Grid.ColumnDefinitions>
<wpfExp:SignalNamePanel Grid.Column="1"
Height="{Binding ElementName=graph_viewer, Path=GraphHeight, Mode=OneWay}"
MainText="Time"
/>
<wpfExp:SignalGraphAxis Grid.Column="2"
Height="{Binding ElementName=graph_viewer, Path=GraphHeight, Mode=OneWay}"
PenWidth="{Binding ElementName=graph_viewer, Path=GraphPenWidth, Mode=OneWay}"
X_Scale="{Binding ElementName=graph_viewer, Path=X_Scale, Mode=OneWay}"
MaxTimeValue="{Binding ElementName=graph_viewer, Path=_SignalDataViewModel.MaxTimeValue, Mode=OneWay}"
/>
</Grid>
<ItemsPresenter/>
</StackPanel>
</ScrollViewer>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="ExpandPath"
Property="Stroke"
Value="#FF1BBBFA"/>
<Setter TargetName="ExpandPath"
Property="Fill"
Value="Transparent"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hi You can use HasItems in Trigger like.
XAML:
<Trigger Property="ItemsControl.HasItems" Value="True">
<Setter Property="Visibility" TargetName="Name" Value="Collapsed"/>
</Trigger>

Resources