How should I set the properties of a Toggle Button in WPF? - c#

This is the source code of Toggle Buttons.
<Window.Resources>
<Style TargetType="CheckBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CheckBox">
<StackPanel Orientation="Horizontal">
<Grid >
<Border Width="45" Height="20" Background="LightGray" CornerRadius="10" Margin="5,0"></Border>
<Border x:Name="button" Height="25" Width="25" CornerRadius="12.5" HorizontalAlignment="Left" ></Border>
</Grid>
<ContentPresenter x:Name="content" Margin="10,0,0,0" Content="{TemplateBinding Content}" VerticalAlignment="Center"/>
</StackPanel>
<ControlTemplate.Resources>
<Storyboard x:Key="right">
<ThicknessAnimation Storyboard.TargetProperty="Margin" Storyboard.TargetName="button" Duration="0:0:0.4" From="0,0,0,0" To="28,0,0,0" >
<ThicknessAnimation.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
<Storyboard x:Key="left">
<ThicknessAnimation Storyboard.TargetProperty="Margin" Storyboard.TargetName="button" Duration="0:0:0.4" From="28,0,0,0" To="0,0,0,0" >
<ThicknessAnimation.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</ThicknessAnimation.EasingFunction>
</ThicknessAnimation>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="false">
<Trigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="leftt"></RemoveStoryboard>
<BeginStoryboard Storyboard="{StaticResource right}" x:Name="rightt" ></BeginStoryboard>
</Trigger.ExitActions>
<Setter TargetName="button" Property="Background" Value="#757575"></Setter>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Trigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="rightt"></RemoveStoryboard>
<BeginStoryboard Storyboard="{StaticResource left}" x:Name="leftt" ></BeginStoryboard>
</Trigger.ExitActions>
<Setter TargetName="button" Property="Background" Value="#20BF55"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel VerticalAlignment="Center">
<CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26" Foreground="#0B4F6C" >Option 1</CheckBox>
<CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26" Foreground="#0B4F6C" >Option 2</CheckBox>
<CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26" Foreground="#0B4F6C" >Option 3</CheckBox>
<CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26" Foreground="#0B4F6C" >Option 4</CheckBox>
<CheckBox HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26" Foreground="#0B4F6C" >Option 5</CheckBox>
</StackPanel>
So what I want to do here is run a command when the toggle button is enabled and run another command when the toggle button is disabled. I am new to WPF. So pls help me to do this and thanks in advance.

Using XAML Behaviors for WPF.
Checkbox example
<CheckBox
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
Content="Some Choice">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding UnCheckedCommand}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding CheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
ToggleButton example
<ToggleButton
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
Content="Some Toggle">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding UnCheckedCommand}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding CheckedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ToggleButton>
You are using CheckBoxes, not ToggleButtons.

Related

"No target method found" error using cal:Message.Attach in WPF Context Menu

I am using Caliburn.Micro. I have tried the solutions I found for this problem but is no good. I have the following XAML code for my design:
<Grid x:Name="ActionGrid">
<MenuItem Header="Action" FontFamily="Open Sans" FontSize="14" HorizontalContentAlignment="Right" Foreground="White" x:Name="miAction" Margin="5" Background="#FF166FC4" Tag="{Binding DataContext}">
<MenuItem.Style>
<Style TargetType="{x:Type MenuItem}">
<Style.Triggers>
<EventTrigger RoutedEvent="Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
<Setter Property="Tag" Value="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MenuItem}}"/>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}">
<MenuItem Header="Remove Group" cal:Message.Attach="RemoveClicked()" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</MenuItem.Style>
</MenuItem>
</Grid>
<UserControl.DataContext>
<vm:TransactionViewModel/>
</UserControl.DataContext>
Everytime I click on the Item, it returns No Method Found for RemoveClicked. I don't know what I did wrong. Please help me point it out.
Tag="{Binding DataContext}" should be Tag="{Binding}" and the cal:Action.TargetWithoutContext attached property should be set on the MenuItem. Then it works if you right click on the MenuItem to open the ContextMenu:
<MenuItem Header="Action" FontFamily="Open Sans" FontSize="14" HorizontalContentAlignment="Right" Foreground="White" x:Name="miAction"
Margin="5" Background="#FF166FC4" Tag="{Binding}">
<MenuItem.Style>
<Style TargetType="{x:Type MenuItem}">
<Style.Triggers>
<EventTrigger RoutedEvent="Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Remove Group"
cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"
cal:Message.Attach="RemoveClicked()" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</MenuItem.Style>
</MenuItem>
Use an EventTrigger to open the ContextMenu on left click doesn't work with bindings and this has nothing to do with Caliburn.Micro:
WPF Context menu on left click
You may replace the EventTrigger with an attached behaviour.
I'm not sure, but you can test this:
<MenuItem Header="Remove Group" cal:Message.Attach="RemoveClicked" />

Columns mentioned in DataGrid.Columns is not visible when AutoGenerateColumns=false in CustomControl DataGrid (WPF Datagrid)

I am trying to Create a Custom Control by extending the DataGrid in WPF, but the problem is that when I use this custom control in view and Provide the specific columns by setting the AutoGenerateColumns to False, the columns is not getting generated. In the OnApplyTemplate() when I tried to fetch the Datagrid through the Template it shows as column count as 0, whereas in the view in code behind it shows the no of columns correctly whatever is specified in the xaml.
Where I am wrong or something extra needs to be set for this?
My Custom control code-
public class DataGridControl: DataGrid
{
static DataGridControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DataGridControl), new FrameworkPropertyMetadata(typeof(DataGridControl)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
DataGrid dataGrid = Template.FindName("PART_DataGrid", this) as DataGrid;
int noOfColumns = dataGrid.Columns.Count// (0 it should come as 3)
}
}
Generic.xaml(inside the Control Template and border)
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
.....
xmlns:local="clr-namespace:Siemens.WPF.DataGridControl">
<LinearGradientBrush x:Key="lightBrushBack" EndPoint="0.5,1" StartPoint="0.5,0">
.....
</LinearGradientBrush>
<LinearGradientBrush x:Key="normalBrushBack" EndPoint="0.5,1" StartPoint="0.5,0">
......
</LinearGradientBrush>
<Style TargetType="{x:Type local:DataGridControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:DataGridControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<DataGrid x:Name="PART_DataGrid"
ItemsSource="{TemplateBinding ItemsSource}"
AutoGenerateColumns="{TemplateBinding AutoGenerateColumns}">
<DataGrid.Resources>
<!--A custom DataGridColumnHeadersPresenter is required to "not" display the custom ColumnHeader template as background of the datagrid header-->
<Style TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
<Grid>
<!--"part_fillercolumnheader" (DataGridColumnHeader type) is removed, and a plain rectangle is placed in its place.-->
<Rectangle Fill="{StaticResource normalBrushBack}" />
<!--Leave the item presenter in its place.-->
<ItemsPresenter x:Name="itemsPresenter" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--End of custom DataGridColumnHeadersPresenter template-->
<!--Custom Column Header Gripper styling-->
<Style x:Key="ColumnHeaderGripperStyle" TargetType="{x:Type Thumb}">
<Setter Property="Width" Value="3"/>
<Setter Property="Foreground" Value="Transparent" />
<Setter Property="Cursor" Value="SizeWE"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Foreground}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--Custom Column Header template to show extra elements in the header-->
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<!--Let's keep the top section grid to contain the DataGridHeaderBorder, and left+right thumbs.-->
<Grid x:Name="fullHeader" Background="{StaticResource normalBrushBack}">
<!--Here is the theme based DataGridHeaderBorder. I've used Aero here.-->
<aero:DataGridHeaderBorder x:Name='HeaderBorder'
SortDirection="{TemplateBinding SortDirection}"
IsHovered="{TemplateBinding IsMouseOver}"
IsPressed="{TemplateBinding IsPressed}"
IsClickable="{TemplateBinding CanUserSort}"
BorderThickness="0,0,1,1"
BorderBrush="{TemplateBinding Foreground}"
Background="Transparent"
SeparatorVisibility="{TemplateBinding SeparatorVisibility}"
SeparatorBrush="#FFC9CACA">
<!--Put 3 elements inside the border: Content of header, a drop down button, and a sort order indicator.-->
<Grid Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition MinHeight="15" Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<!--For ContentPresenter-->
<ColumnDefinition Width="*" />
<!--For drop down button-->
<ColumnDefinition Width="23" />
<!--For sort order indicator-->
<ColumnDefinition Width="12" />
</Grid.ColumnDefinitions>
<!--A hidden rectangle is placed to be shown when mouse hovers on the column (to highlight the column.)-->
<Rectangle x:Name="HoverRectangle"
Stretch="Fill"
Grid.ColumnSpan="3"
Fill="{StaticResource lightBrushBack}"
Opacity="0"
StrokeThickness="0" />
<!--Content of the header.-->
<ContentPresenter Grid.Column="0"
Grid.Row="0"
Margin="2,0,0,0"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
Cursor="{TemplateBinding Cursor}" />
<!--A drop down filter button.-->
<Button x:Name="PART_FilterBtn"
HorizontalAlignment="Right"
Command="{Binding FilterClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"
CommandParameter="{Binding ElementName=HeaderBorder}"
Grid.Row="0" Cursor="Hand"
Grid.Column="1">
<Button.Template>
<ControlTemplate>
<Path Data="M 0,0 L 1,1 1,3 2,3 2,1 3,0 Z"
Stretch="UniformToFill"
Stroke="{TemplateBinding Foreground}"
Fill="{TemplateBinding Foreground}"
Margin="4,4,0,4"/>
</ControlTemplate>
</Button.Template>
</Button>
<Path x:Name="PART_SortArrow"
Grid.Column="2"
HorizontalAlignment="Center" VerticalAlignment="Center"
Width="8"
RenderTransformOrigin=".5,.5"
Visibility="Visible"
Fill="{TemplateBinding Foreground}"
Stretch="Uniform"
Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z">
</Path>
</Grid>
</aero:DataGridHeaderBorder>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="SortDirection" Value="Descending">
<Setter TargetName="PART_SortArrow" Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="180" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property='IsMouseOver' SourceName="fullHeader" Value='True'>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="00:00:00" Duration="00:00:00.20000"
Storyboard.TargetName="HoverRectangle"
Storyboard.TargetProperty="(UIElement.Opacity)"
To='1.0' />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="00:00:00" Duration="00:00:00.20000"
Storyboard.TargetName="HoverRectangle"
Storyboard.TargetProperty="(UIElement.Opacity)"
To='0' />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush options:Freeze="True" StartPoint="0.504,0.03" EndPoint="0.504,1.5">
<GradientStop Offset="0.0" Color="#E3F7FF" />
<GradientStop Offset="0.3" Color="#E3F7FF" />
<GradientStop Offset="0.35" Color="#BCECFE" />
<GradientStop Offset="1.0" Color="#B9E9FC" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="#69BBE3" />
</DataTrigger>
</Style.Triggers>
</Style>
<!--End of custom DataGridColumnHeader template-->
</DataGrid.Resources>
</DataGrid>
<Popup x:Name="PART_PopUp"
Grid.Column="3"
AllowsTransparency="True"
AllowDrop="True"
Width="200"
Height="253"
MinHeight="253"
MaxHeight="253"
PopupAnimation="Slide"
VerticalOffset="-15"
IsOpen="{Binding IsFilterPopUpVisible,RelativeSource={RelativeSource AncestorType=local:DataGridControl}}"
PlacementTarget="{Binding ElementName=PART_FilterBtn}"
StaysOpen="False"
Placement="Mouse" >
<Border Background="White" BorderBrush="DarkGray" BorderThickness="2">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" Margin="10,5,0,5">
<Button Margin="10,0,0,0" Name="PART_SelectAllBtn" Command="{Binding SelectAllClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}" CommandParameter="{Binding ElementName=PART_ListBox}" >
<Button.Template>
<ControlTemplate>
<TextBlock Text="Select All" Foreground="Blue" Cursor="Hand" />
</ControlTemplate>
</Button.Template>
</Button>
<Button Margin="30,0,0,0" Name="PART_SelectNoneBtn" Command="{Binding SelectNoneClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}" CommandParameter="{Binding ElementName=PART_ListBox}" >
<Button.Template>
<ControlTemplate>
<TextBlock Text="Select None" Foreground="Blue" Cursor="Hand" />
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
<TextBox x:Name="PART_TextBox" Width="185" Height="25" Text="" Margin="3,0,3,3"/>
<ListBox x:Name="PART_ListBox"
Height="160"
MaxHeight="160"
MinHeight="160"
Width="185"
SelectionMode="Multiple"
DisplayMemberPath="Value"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
ItemsSource="{Binding FilterCollectionList, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}" Margin="0,0,0,5"
ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem" >
<CheckBox x:Name="PART_CheckBox" Margin="5,2" IsChecked="{Binding IsSelected}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding CheckedCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"/>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding CheckedCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ContentPresenter />
</CheckBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<StackPanel Orientation="Horizontal" Margin="0,0,0,15" HorizontalAlignment="Center">
<Button x:Name="PART_OkBtn" Height="22" Width="70" Content="Ok"
IsEnabled="{Binding IsOkButtonEnabled, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"
Command="{Binding OkButtonClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"
/>
<Button x:Name="PART_CancelBtn" Height="22" Width="70" Content="Cancel" Margin="5,0,0,0"
Command="{Binding CancelButtonClickCommand, RelativeSource={RelativeSource AncestorType={x:Type local:DataGridControl}}}"
/>
</StackPanel>
</StackPanel>
</Border>
</Popup>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
MainWindow.xaml
<dataGrid:DataGridControl x:Name="dataGridControl" AutoGenerateColumns="False">
<dataGrid:DataGridControl.Columns>
<DataGridTextColumn Header="RollNo" Binding="{Binding RollNo}" />
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}" />
</dataGrid:DataGridControl.Columns>
</dataGrid:DataGridControl>
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
List<Student> studList =
new List<Student>() { new Student { RollNo = 1, Name = "Full Name
1", FirstName = "FirstName1", LastName="LastName1", Address =
"Pune1", PinCode= "411057"},};
dataGridControl.ItemsSource = studList;
int noOfColumns = dataGridControl.Columns.Count; //(showing 3 as expected)
}
Create property for custom control
#region GridColumns
private ObservableCollection<DataGridColumn> _gridColumns;
public ObservableCollection<DataGridColumn> GridColumns
{
get => _gridColumns;
}
#endregion GridColumns
Add columns from created property using method OnApplyTemplate
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (!AutoGenerateColumns)
{
var grid = GetTemplateChild("PART_Grid") as DataGrid;
foreach (var column in _gridColumns)
grid.Columns.Add(column);
}
}
Change MainWindow.xaml
<dataGrid:DataGridControl x:Name="dataGridControl" AutoGenerateColumns="False">
<dataGrid:DataGridControl.GridColumns>
<DataGridTextColumn Header="RollNo" Binding="{Binding RollNo}" />
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}" />
</dataGrid:DataGridControl.GridColumns>
</dataGrid:DataGridControl>

WPF Move control based on other control

I've got the following <canvas>:
<Canvas>
<ToggleButton Height="30" Width="125" Name="DisplayCanvas"
Background="Transparent"
BorderBrush="Transparent" Canvas.ZIndex="1" Cursor="Hand"
ClickMode="Press" Canvas.Top="11">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<Image Source="../Images/Button/customise.png" Height="30" Width="30" Canvas.Top="11"/>
<Label Content="Customize" VerticalAlignment="Center" Canvas.Left="31" Canvas.Top="14" Foreground="White"/>
<Path Data="M0,10 L5,0 L10,10" Stroke="White"
Height="8"
StrokeThickness="2" HorizontalAlignment="Center" Canvas.Left="101.733"
Canvas.Top="22" Stretch="Fill" Width="15">
<Path.Style>
<Style TargetType="Path">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=DisplayCanvas, Path=IsChecked}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=DisplayCanvas, Path=IsChecked}" Value="False">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
<Path Data="M0,10 L5,0 L10,10" Stroke="White" StrokeThickness="2" HorizontalAlignment="Center" Canvas.Left="102" Height="8" Canvas.Top="23.733" Stretch="Fill" Width="15" RenderTransformOrigin="0.5,0.5">
<Path.Style>
<Style TargetType="Path">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=DisplayCanvas, Path=IsChecked}" Value="True">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=DisplayCanvas, Path=IsChecked}" Value="False">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
<EventTrigger RoutedEvent="Path.Loaded">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" BeginTime="0:0:0" Duration="0:0:1" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Path.Style>
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="181.918"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
<Button Content="" Height="30" Width="65"
Background="Transparent" BorderBrush="Transparent" Canvas.ZIndex="1" Cursor="Hand" Canvas.Top="128">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction
Command="{Binding Help}"
CommandParameter="{Binding RelativeSource= {RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext}">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Image Source="../Images/Button/help.png" Height="30" Width="30" Canvas.Top="128"></Image>
<Label Content="Help" VerticalAlignment="Center" Canvas.Left="32" Canvas.Top="131" Foreground="White"></Label>
<Canvas Visibility="{Binding IsChecked, ElementName=DisplayCanvas, Converter={StaticResource InverseBooleanToVisibilityConverter}}" Name="CustomisationCanvas">
<Button Content="" Height="30" Width="71" Canvas.Top="57"
Background="Transparent" BorderBrush="Transparent" Canvas.ZIndex="1" Cursor="Hand" Canvas.Left="44">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction
Command="{Binding CustomiseAvatar}"
CommandParameter="{Binding RelativeSource= {RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext}">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Image Source="../Images/Button/customise.png" Height="30" Width="30" Canvas.Top="56" Canvas.Left="44"></Image>
<Label Content="Avatar" VerticalAlignment="Center" Canvas.Left="74" Canvas.Top="60" Foreground="White"></Label>
<Button Content="" Height="30" Width="71" Canvas.Top="97"
Background="Transparent" BorderBrush="Transparent" Canvas.ZIndex="1" Cursor="Hand" Canvas.Left="44">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction
Command="{Binding CustomiseSkin}"
CommandParameter="{Binding RelativeSource= {RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext}">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Image Source="../Images/Button/customise.png" Height="30" Width="30" Canvas.Top="97" Canvas.Left="44"/>
<Label Content="Skin" VerticalAlignment="Center" Canvas.Left="74" Canvas.Top="100" Foreground="White"/>
</Canvas>
</Canvas>
What I need to do is when the canvas is displayed, I need to move the HelpButton down, when it is hidden, move the HelpButton back up.Is this possible? Almost like a ContextMenu.
You could try to use a Button style that binds to the Visibility property of the Canvas and sets the Canvas.Top attached property of the Button:
<Button Content="" Height="30" Width="65" Background="Transparent" BorderBrush="Transparent" Canvas.ZIndex="1" Cursor="Hand">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Canvas.Top" Value="128" />
<Style.Triggers>
<DataTrigger Binding="{Binding Visibility, ElementName=CustomisationCanvas}" Value="Collapsed">
<Setter Property="Canvas.Top" Value="100" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction
Command="{Binding Help}"
CommandParameter="{Binding RelativeSource= {RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=DataContext}">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
i think your massively over complicating your layout
Here is a simpler example that uses a Toggle to show and hide content
<StackPanel>
<HeaderedContentControl >
<HeaderedContentControl.Header>
<ToggleButton x:Name="toggleShow">Show/Hide</ToggleButton>
</HeaderedContentControl.Header>
<StackPanel Visibility="{Binding IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=toggleShow}">
<Label>test</Label>
<Label>test</Label>
<Label>test</Label>
</StackPanel>
</HeaderedContentControl>
<Label>help</Label>
</StackPanel>

C# WPF, how to make a label with a delete button on it?

I'm trying to make a File Attachment function in my program, i have 2 types of attachments (Personal/Professional documents). Picture below.
What i want to do now, is make the uploaded files appear in a vertical list (below the label & button in each groupbox) as a label with a delete button, i dont know what this function is called. I would like something like the keywords/tags function (like on stackoverflow, youtube...) Picture below.
Like:
Drivers License [X]
Passport [X]
Visa [X]
As the user can quickly see what files he have alredy uploaded, and quickly remove a file if he made a mistake.
What i have tried so far, is making a stackpanel divided into 2 columns, text on one side, and buttons on the other side, but i didnt get the result that i wanted. Problem is that i dont even know what this function is called, im sure Theres some tutorial somewhere out there, but its hard to search for something you dont know the name of.
Use ListView with the style:
<Style x:Key="ListViewPlate" TargetType="{x:Type ListView}">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding (FrameworkElement.ActualWidth),
RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
ItemWidth="{Binding (ListView.View).ItemWidth,
RelativeSource={RelativeSource AncestorType=ListView}}"
MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
ItemHeight="{Binding (ListView.View).ItemHeight,
RelativeSource={RelativeSource AncestorType=ListView}}" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
And ListView ItemTemplate - in order to works with the delete button use Command (that would require using a Prism), command would transfer selected item as a context.
<DataTemplate x:Key="ListViewPlateItem">
<WrapPanel>
<Border Background="Black" />
<Border BorderBrush="Goldenrod" BorderThickness="2">
<TextBlock HorizontalAlignment="Center" Text="{Binding Name}" VerticalAlignment="Center" />
</Border>
<Border BorderBrush="Goldenrod" BorderThickness="2">
<Button Command="{Binding ElementName = ListViewElement, Path = DataContext.Command"} CommandParameter={"Binding"}">
<Button.Background>
<ImageBrush ImageSource="yourImage.png" TitleMode="None"/>
</Button.Background>
</Button>
</Border>
</WrapPanel>
</DataTemplate>
You can made style and ItemTemplate a ResourceDictionary, and then use it
<ListView ItemTemplate="{StaticResource ListViewPlateItem}" Style="{StaticResource ListViewPlate}"/>
Here is UserControl that is looking like
Xaml code
<UserControl x:Class="ButtonLikeInSO.SpecialTextPresenterWithButton"
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="150" x:Name="This">
<UserControl.Resources>
<SolidColorBrush x:Key="GrayButtonBackGround" Color="Gainsboro"/>
<SolidColorBrush x:Key="RedButtonBackground" Color="Tomato"/>
<Style x:Key="ChangeContentOnMouseOverWithAnimationWhenPressed" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="{StaticResource GrayButtonBackGround}"/>
<Setter Property="Foreground" Value="Black"></Setter>
<Setter Property="ToolTip" Value="Delete Uploading"/>
<Setter Property="ToolTipService.Placement" Value="Top"/>
<Setter Property="Opacity" Value="0.8"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="LayoutRoot" RenderTransformOrigin="0.5 0.5" Margin="2">
<Grid.RenderTransform>
<ScaleTransform></ScaleTransform>
</Grid.RenderTransform>
<Ellipse x:Name="MyBorder" Fill="{TemplateBinding Background}" Stroke="Gray" StrokeThickness="1"/>
<Ellipse x:Name="RectangleVisibleOnMouseMove" Opacity="0" Fill="{StaticResource RedButtonBackground}" Stroke="Black" StrokeThickness="1"/>
<Path x:Name="ButtonPath"
Margin="5"
Stroke="{TemplateBinding Foreground}"
StrokeThickness="1.5"
StrokeStartLineCap="Square"
StrokeEndLineCap="Square"
Stretch="Uniform"
VerticalAlignment="Center"
HorizontalAlignment="Center" Data="M0,0 L1,1 M0,1 L1,0">
</Path>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="RectangleVisibleOnMouseMove"
Storyboard.TargetProperty="(FrameworkElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0.0" />
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="1.0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyBorder"
Storyboard.TargetProperty="(FrameworkElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="RectangleVisibleOnMouseMove"
Storyboard.TargetProperty="(FrameworkElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="MyBorder"
Storyboard.TargetProperty="(FrameworkElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0.0" />
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="1.0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.PreviewMouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.10" Value="0.8" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
<EasingDoubleKeyFrame KeyTime="0:0:0.10" Value="0.8" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.PreviewMouseUp">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0.8" />
<EasingDoubleKeyFrame KeyTime="0:0:0.10" Value="1.0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot"
Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0.8" />
<EasingDoubleKeyFrame KeyTime="0:0:0.10" Value="1.0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Button.IsPressed" Value="True">
<Setter Property="Foreground" Value="White"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="False">
<Setter Property="Foreground" Value="Black"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="1.0"></Setter>
</Trigger>
</Style.Triggers>
</Style>
<DataTemplate x:Key="TextWithDeleteButton">
<Border BorderThickness="1" BorderBrush="Gainsboro">
<Grid Background="{Binding ElementName=This, Path=Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding ElementName=This, Path=Text}" MaxWidth="150" Margin="5,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center"
TextTrimming="WordEllipsis" />
<Button Grid.Column="1" Margin="0" Width="20" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center" Command="{Binding ElementName=This, Path=DeleteCommand}" Style="{StaticResource ChangeContentOnMouseOverWithAnimationWhenPressed}"></Button>
</Grid>
</Border>
</DataTemplate>
</UserControl.Resources>
<Grid>
<ContentControl ContentTemplate="{StaticResource TextWithDeleteButton}"></ContentControl>
</Grid>
Code behind
public partial class SpecialTextPresenterWithButton : UserControl
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof (string),
typeof (SpecialTextPresenterWithButton), new PropertyMetadata(default(string)));
public static readonly DependencyProperty DeleteCommandProperty = DependencyProperty.Register("DeleteCommand",
typeof (ICommand), typeof (SpecialTextPresenterWithButton), new PropertyMetadata(default(ICommand)));
public SpecialTextPresenterWithButton()
{
InitializeComponent();
}
public string Text
{
get { return (string) GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public ICommand DeleteCommand
{
get { return (ICommand) GetValue(DeleteCommandProperty); }
set { SetValue(DeleteCommandProperty, value); }
}
}
Using
<!--you can use binding to DeleteCommand and Text they are dependancy properties-->
<buttonLikeInSo:SpecialTextPresenterWithButton Background="Aquamarine" DeleteCommand="{Binding DeleteCommand}" HorizontalAlignment="Center" VerticalAlignment="Center" Height="20" Text="LoooooooooooongFileName"/>
Assuming you have some type of View Model with data-binding, this can be quite straight forward. You can have an ObservableCollection of uploaded items. This could just be a simple class holding an identifyer and display name:
public class UploadedFileInfo
{
public int Id { get; set; }
public string DisplayName { get; set; }
}
in View Model:
ObservableCollection<UploadedFileInfo> UploadedFiles { get; set; }
Now you can bind a ItemsControl to this collection eg:
<ItemsControl ItemsSource="{Binding UploadedFiles}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding DisplayName, Mode=OneWay}" />
<Button Command="{Binding Path=DataContext.DeleteFile, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding Id}" />
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This requires a command in the View Model:
public ICommand DeleteFile { get; private set;}
In View Model Constructor:
DeleteFile = new RelayCommand<int>((fileIdToDelete) => deleteFile(fileIdToDelete))
Where deleteFile(int fileToDelete) is a function to delete the file and remove it from the ObservableCollection UploadedFiles
Note, you will have to find the RelayCommand class, there is one on the Microsoft WPF pages, there are also implementations in MVVMLight and other MVVM frameworks that you can use.
EDIT
A binding in an ItemsControl will look for properties on the objects bound to (that is its DataContext)
<Button Command="{Binding DeleteFile}" CommandParameter="{Binding Id}" />
Should have been
<Button Command="{Binding Path=DataContext.DeleteFile, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding Id}" />
Which will look for the ICommand parameter on the main window's DataContext

wpf button storyboard trigger

I am trying to make rectangle animation after clicking on a button.
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
<Button Content="FirstButton" HorizontalAlignment="Left" Height="60" Margin="341,91,0,0" VerticalAlignment="Top" Width="91">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
??? <BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
What i need to write?
<StackPanel>
<Button Name="Button"/>
<Rectangle>
<Rectangle.Style>
<Style TargetType="Rectangle">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Button, Path=IsPressed}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</StackPanel>

Categories