Button event is not triggered from Listbox item template wpf - wpf

Here is my xaml
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Blue"
BorderThickness="1"
HorizontalAlignment="Stretch">
<StackPanel HorizontalAlignment="Stretch"
Orientation="Horizontal">
<TextBlock Margin="5"
Text="{Binding Text}" />
<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
Click="Remove">
<Button.Content>
<Image Source="{Binding DeleteIcon}"
Stretch="Fill"
Height="15"
Width="20" />
</Button.Content>
</Button>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
button event is not triggered in code behind or in viewmodel with command binding. How to fix this?

Trying this... It's work for me....
<ListBox Name="lstNumbers">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Blue"
BorderThickness="1"
HorizontalAlignment="Stretch">
<StackPanel HorizontalAlignment="Stretch"
Orientation="Horizontal">
<TextBlock Margin="5"
Text="{Binding Text}" />
<Button Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
Click="Remove">
<Button.Content>
<Image Source="{Binding DeleteIcon}"
Stretch="Fill"
Height="15"
Width="20" />
</Button.Content>
</Button>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Cs Code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<Numbers> list = new List<Numbers>();
list.Add(new Numbers() { Text ="1"});
list.Add(new Numbers() { Text = "2" });
lstNumbers.ItemsSource = list;
}
private void Remove(object sender, RoutedEventArgs e)
{
}
public class Numbers
{
public string Text { get; set; }
}

Related

WPF MVVM Combobox SelectionChanged just after reload the ViewModel

My problem is, after the SelectionChanged event nothing happen. The TextBox didnt get any new value relaited to the ComboBox. When I reload the ViewModel (Go page 1 and back), the TexBox has his new value relaited to the ComboBox.
Below you can see what I have on till now.
View:
<StackPanel Orientation="Vertical" Grid.Row="1">
<Border Width="150" Height="150" CornerRadius="80" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Center">
<Border.Background>
<ImageBrush ImageSource="/Assets/FEBSolution.png"/>
</Border.Background>
</Border>
<TextBlock x:Name="EmployerName" Text="{Binding EmployerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Margin="0 10 0 0" FontWeight="Bold"/>
<TextBlock x:Name="EmpDescription" Text="{Binding EmpDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="11" HorizontalAlignment="Center" Opacity="0.8"/>
<TextBlock x:Name="EmpMotto" Text="{Binding EmpMotto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="8" HorizontalAlignment="Center" Opacity="0.8"/>
<StackPanel Margin="20">
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Location" />
<TextBlock x:Name="EmpLocation" Text="{Binding EmpLocation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Phone" />
<TextBlock x:Name="EmpPhone" Text="{Binding EmpPhone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Email" />
<TextBlock x:Name="EmpEmail" Text="{Binding EmpEmail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
</StackPanel>
</StackPanel>
<ComboBox x:Name="cmbEmployer" Grid.Row="2" SelectedValuePath="ID" SelectedValue="{Binding ID}" ItemsSource="{Binding contractDetails}" SelectedItem="{Binding ContractSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="EmployerName" materialDesign:HintAssist.Hint="Employer" Width="200" HorizontalAlignment="Center" Margin="10">
<ie:Interaction.Triggers>
<ie:EventTrigger EventName="SelectionChanged">
<ie:InvokeCommandAction Command="{Binding SelectionChangedCommand, UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding ElementName=cmbEmployer, Path=SelectedItem}"/>
</ie:EventTrigger>
</ie:Interaction.Triggers>
</ComboBox>
ViewModel:
private ContractDetail _contractSelectedItem;
public ContractDetail ContractSelectedItem
{
get { return _contractSelectedItem; }
set
{
_contractSelectedItem = value;
EmployerName = _contractSelectedItem.EmployerName;
EmpDescription = _contractSelectedItem.EmpDescription;
EmpMotto = _contractSelectedItem.EmpMotto;
EmpLocation = _contractSelectedItem.EmpLocation;
EmpPhone = _contractSelectedItem.EmpPhone;
EmpEmail = _contractSelectedItem.EmpEmail;
OnPropertyChanged(nameof(ContractSelectedItem));
}
}
public List<ContractDetail> contractDetails { get; set; }
#region Public all Commands
//Command for change User
public ICommand ChangeUserCommand { get; private set; }
public ICommand CloseWindowCommand { get; private set; }
public ICommand SelectionChangedCommand { get; private set; }
#endregion
//PRWContext for general use
private PRWContext context = new PRWContext();
public ApplicationSettingViewModel()
{
// Load the data from PRW Database
LoadUserData();
BindContractComboBox();
//Commands
ChangeUserCommand = new RelayCommand(() => ExecuteChangeUserCommand());
CloseWindowCommand = new RelayCommand(() => ExecuteCloseWindowCommand());
SelectionChangedCommand = new RelayCommand(() => ExecuteSelectionChangedCommand());
}
private void ExecuteCloseWindowCommand()
{
foreach (Window window in Application.Current.Windows)
{
if (window is ApplicationSettingWindow)
{
window.Close();
break;
}
}
}
private void ExecuteChangeUserCommand()
{
UserSettingWindow view = new UserSettingWindow();
view.Show();
foreach (Window window in Application.Current.Windows)
{
if (window is ApplicationSettingWindow)
{
window.Close();
break;
}
}
}
private void ExecuteSelectionChangedCommand()
{
var item = context.ContractDetails.ToList();
contractDetails = item;
}
//Load the user data
private void LoadUserData()
{
UserName = Settings.Default["UserName"].ToString();
JobDescription = Settings.Default["UsrJobDescription"].ToString();
Motto = Settings.Default["UsrMotto"].ToString();
Street = Settings.Default["UsrStreet"].ToString();
City = Settings.Default["UsrCity"].ToString();
Country = Settings.Default["UsrCountry"].ToString();
PhoneNumber = Settings.Default["UsrPhoneNumber"].ToString();
Email = Settings.Default["UsrEmail"].ToString();
}
private void BindContractComboBox()
{
var item = context.ContractDetails.ToList();
contractDetails = item;
}
#region PropertyChanged EventHandler
//propertychanged eventhandler
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
For sure there is somthing missing, otherwise it will do the magic ;) I just dont know where i miss something. Any help will be welcome.
You aren't calling the OnPropertyChanged() for
EmployerName,
EmpDescription,
EmpMotto,
EmpLocation,
EmpPhone,
EmpEmail
that's why your view doesn't get updated, and why are you actually using these separate properties when you can just use the ContractSelectedItem directly. You can access the nested properties like this "ContractSelectedItem.EmployerName"
Try this in your viewmodel
private ContractDetail _contractSelectedItem;
public ContractDetail ContractSelectedItem
{
get { return _contractSelectedItem; }
set
{
_contractSelectedItem = value;
OnPropertyChanged(nameof(ContractSelectedItem));
}
}
and change your view's binding like this
<StackPanel Orientation="Vertical" Grid.Row="1">
<Border Width="150" Height="150" CornerRadius="80" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Center">
<Border.Background>
<ImageBrush ImageSource="/Assets/FEBSolution.png"/>
</Border.Background>
</Border>
<TextBlock x:Name="EmployerName" Text="{Binding ContractSelectedItem.EmployerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Margin="0 10 0 0" FontWeight="Bold"/>
<TextBlock x:Name="EmpDescription" Text="{Binding ContractSelectedItem.EmpDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="11" HorizontalAlignment="Center" Opacity="0.8"/>
<TextBlock x:Name="EmpMotto" Text="{Binding ContractSelectedItem.EmpMotto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="8" HorizontalAlignment="Center" Opacity="0.8"/>
<StackPanel Margin="20">
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Location" />
<TextBlock x:Name="EmpLocation" Text="{Binding ContractSelectedItem.EmpLocation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Phone" />
<TextBlock x:Name="EmpPhone" Text="{Binding ContractSelectedItem.EmpPhone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Email" />
<TextBlock x:Name="EmpEmail" Text="{Binding ContractSelectedItem.EmpEmail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
</StackPanel>
</StackPanel>
<ComboBox x:Name="cmbEmployer" Grid.Row="2" SelectedValuePath="ID" SelectedValue="{Binding ID}" ItemsSource="{Binding contractDetails}" SelectedItem="{Binding ContractSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="EmployerName" materialDesign:HintAssist.Hint="Employer" Width="200" HorizontalAlignment="Center" Margin="10">
<ie:Interaction.Triggers>
<ie:EventTrigger EventName="SelectionChanged">
<ie:InvokeCommandAction Command="{Binding SelectionChangedCommand, UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding ElementName=cmbEmployer, Path=SelectedItem}"/>
</ie:EventTrigger>
</ie:Interaction.Triggers>
</ComboBox>
Also, there doesn't seem a reason to use the SelectionChanged event when you are just repopulating the contractDetails property every time the selection changes. Try to remove it if you aren't doing anything other then just repopulating the property.

How to use WrapPanel's DataTemplate

I've a WrapPanel to show some elements. But I want to use DataTemplate to show them.
Here is my XAML code of WrapPanel
<WrapPanel Margin="10,57,12,10" x:Name="wrp1">
<WrapPanel.Resources>
<DataTemplate DataType="{x:Type local:DateItem}">
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch" Width="250" Height="300" Background="Blue">
<Label Content="{Binding Path=DateString}" FontSize="20" Cursor="Hand" Foreground="White" Background="Red" FontWeight="Bold" VerticalAlignment="Bottom" HorizontalAlignment="Left" Height="38" VerticalContentAlignment="Center" Padding="5,0,5,0"/>
</Grid>
</DataTemplate>
</WrapPanel.Resources>
</WrapPanel>
And this is the code of DateItem
public class DateItem : UIElement
{
public string DateString { get; set; }
}
When the window initialized, i'm creating one DateItem with DateString parameter and adding that to WrapPanel as child.
DateItem di = new DateItem();
di.DateString = "28.04.2014";
wrp1.Children.Add(di);
I think everything is fine but wrap panel shows nothing :(
Can you help me with this?
You have confused UI controls with DataTemplates which is used to define the presentation of your data. To render data, you have to set content of control which can be done using ContentControl.
Also, you can use ItemsControl if you want to add multiple times.
XAML:
<WrapPanel x:Name="wrp1">
<WrapPanel.Resources>
<DataTemplate DataType="{x:Type local:DateItem}">
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch" Width="250"
Height="300" Background="Blue">
<Label Content="{Binding Path=DateString}" FontSize="20" Cursor="Hand"
Foreground="White" Background="Red" FontWeight="Bold"
VerticalAlignment="Bottom" HorizontalAlignment="Left"
Height="38" VerticalContentAlignment="Center"
Padding="5,0,5,0"/>
</Grid>
</DataTemplate>
</WrapPanel.Resources>
<ItemsControl x:Name="itemsControl"/>
</WrapPanel>
Code behind:
DateItem di = new DateItem();
di.DateString = "28.04.2014";
itemsControl.Items.Add(di);
DateItem:
public class DateItem
{
public string DateString { get; set; }
}
In case you still interested in rendering it as a Control, you have to define default Style and not default template.
XAML:
<WrapPanel x:Name="wrp1">
<WrapPanel.Resources>
<Style TargetType="{x:Type local:DateItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch"
Width="250" Height="300" Background="Blue">
<Label
Content="{Binding Path=DateString, RelativeSource=
{RelativeSource Mode=TemplatedParent}}"
FontSize="20" Cursor="Hand" Foreground="White"
Background="Red" FontWeight="Bold"
VerticalAlignment="Bottom"
HorizontalAlignment="Left"
Height="38" VerticalContentAlignment="Center"
Padding="5,0,5,0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</WrapPanel.Resources>
</WrapPanel>
Code behind:
DateItem di = new DateItem();
di.DateString = "28.04.2014";
wrp1.Children.Add(di);
DateItem:
public class DateItem : Control
{
public string DateString { get; set; }
}

Add second image to content of button

This is the peace of code for the button:
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" CornerRadius="8">
<Border.Background>
SlateBlue
</Border.Background>
<StackPanel Orientation="Horizontal" Margin="3">
<Image Source="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" Height="30" Width="30" Stretch="Fill" Margin="0 0 0 0" />
<TextBlock Text="{Binding Path=Content,RelativeSource={RelativeSource TemplatedParent}}" FontSize="12" VerticalAlignment="Center" Padding="10,0,10,0" />
</StackPanel>
</Border>
</ControlTemplate>
</Button.Template>
As you can see, my button has an image and a text. However, I want to add another image after the text. How do I do this? I already use the Tag property once.
Here's how I use the button:
<myProject:ButtonWithTwoImages x:Name="btnHome" Tag="/Resources/Home.png" Content="Home" Command="{Binding Path=NavigateToCategoriesCommand}" Margin="20 0 0 0"/>
How do I add another image to the button?
I created a new user control called ButtonWithTwoImages, here is the code.
Xaml
<UserControl x:Class="WpfUserControl.ButtonWithTwoImages"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Border x:Name="border" CornerRadius="8">
<Border.Background>
SlateBlue
</Border.Background>
<StackPanel Orientation="Horizontal" Margin="3">
<Image Source="{Binding Path=Image1, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" Height="30" Width="30" Stretch="Fill" Margin="0 0 0 0" />
<TextBlock Text="{Binding Path=Content,RelativeSource={RelativeSource TemplatedParent}}" FontSize="12" VerticalAlignment="Center" Padding="10,0,10,0" />
<Image Source="{Binding Path=Image2, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" Height="30" Width="30" Stretch="Fill" Margin="0 0 0 0" />
</StackPanel>
</Border>
</UserControl>
Xaml.cs
public partial class ButtonWithTwoImages : UserControl
{
public ButtonWithTwoImages()
{
InitializeComponent();
}
public ImageSource Image1
{
get { return (ImageSource)GetValue(Image1Property); }
set { SetValue(Image1Property, value); }
}
public static readonly DependencyProperty Image1Property = DependencyProperty.Register("Image1", typeof(ImageSource), typeof(ButtonWithTwoImages), new PropertyMetadata(null));
public ImageSource Image2
{
get { return (ImageSource)GetValue(Image2Property); }
set { SetValue(Image2Property, value); }
}
public static readonly DependencyProperty Image2Property = DependencyProperty.Register("Image2", typeof(ImageSource), typeof(ButtonWithTwoImages), new PropertyMetadata(null));
}
How To Use It
<Window x:Class="WpfUserControl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mylib="clr-namespace:WpfUserControl">
<Grid>
<mylib:ButtonWithTwoImages Image1="Images\A.jpg" Image2="Images\B.jpg"></mylib:ButtonWithTwoImages>
</Grid>
</Window>

Databinding custom objects

public class Employee : INotifyPropertyChanged
{
// Private Properties
private string _name;
private List<string> _address;
// The Public properties for which the getters and setters are implemented appropriately (raising OnPropertyChanged event)
}
public class EmployeeRecords: ObservableCollection<Employee>
{
public bool AddEmployee(Employee employee)
{
Add(employee);
return true;
}
public bool RemoveEmployee(int index)
{
if (Count > 0)
{
RemoveAt(index); // is the same as doing 'RemoveAt(SelectedIndex);'
}
return true;
}
}
**XAML:**
<Window x:Class="EmployeeInfo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:EmployeeInfo"
Name="Page1" Height="225" Width="610"
Title="DATABINDING DEMO">
<Window.Resources>
<DataTemplate x:Key="EmployeeTemplate">
<StackPanel>
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=EmpId}"/>
<TextBlock Text="{Binding Path=Designation}"/>
</StackPanel>
</DataTemplate>
<src:EmployeeRecords x:Key="EmpInfo"/>
</Window.Resources>
<Window.DataContext>
<Binding Source="{StaticResource EmpInfo}"/>
</Window.DataContext>
<Canvas Height="190" Width="600">
<Label Name="lblName" Height="30" Width="50" Canvas.Top="0" Canvas.Left="0" >Name</Label>
<TextBox Name="txtBoxName" Height="30" Width="125" Text="{Binding Path=Name}" Canvas.Top="5" Canvas.Left="60" />
<Label Name="lblEmpId" Height="30" Width="50" Canvas.Top="40" Canvas.Left="0" >EmpId</Label>
<TextBox Name="txtBoxEmpId" Height="30" Width="50" Text="{Binding Path=EmpId}" Canvas.Top="40" Canvas.Left="60" />
<Label Name="lblDesignation" Height="30" Width="50" Canvas.Top="75" Canvas.Left="0" >Designation</Label>
<TextBox Name="txtBoxDesignation" Height="30" Width="50" Text="{Binding Path=Designation}" Canvas.Top="75" Canvas.Left="60" />
<Label Name="lblAddress" Height="30" Width="50" Canvas.Top="115" Canvas.Left="0" >Address</Label>
<TextBox Name="txtBoxAddress" Height="30" Width="50" Text="{Binding Path=Address}" Canvas.Top="115" Canvas.Left="60" />
<TextBox Name="txtBoxAddress2" Height="30" Width="50" Text="{Binding Path=Address}" Canvas.Top="115" Canvas.Left="120" />
<Button Height="30" Width="50" Canvas.Top="155" Canvas.Left="0" Content="Update" Click="UpdateButton_Click"/>
<Button Height="30" Width="50" Canvas.Top="155" Canvas.Left="60" Content="Submit" Click="SubmitButton_Click"/>
<Button Height="30" Width="50" Canvas.Top="155" Canvas.Left="120" Content="Remove" Click="RemoveButton_Click" />
<ListBox SelectedIndex="{Binding SelectedIndex}"
MouseDoubleClick="LstEmployee_MouseDoubleClick" Name="lstEmployee" Height="180" Width="190"
Canvas.Top="5" Canvas.Left="200" ItemsSource="{Binding}" ItemTemplate="{StaticResource EmployeeTemplate}"/>
<ListBox Name="listAddress" Height="180" Width="190" Canvas.Top="5" Canvas.Left="400" ItemsSource="{Binding Path=/Address}"/>
</Canvas>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
private EmployeeRecords _empRecords;
public MainWindow()
{
InitializeComponent();
Initialize();
lstEmployee.ItemsSource = _empRecords;
}
.
.
.
.
}
I'm trying to display all the properties of Employee in the 1st listBox and just the addresses in the 2nd ListBox. Can someone tell me what i'm doing wrong here?
Since I can't explicitly access the Employee object within EmployeeRecords, how can I bind the Address list inside of Employee to a control?
Thanks in advance!
Shanks
Assuming that you want to display the address of the selected Employee in the second ListBox, the following should work.
<ListBox Grid.Row="1" Name="listAddress" Height="180" Width="190" Canvas.Top="5" Canvas.Left="400" ItemsSource="{Binding ElementName=lstEmployee, Path=SelectedItem.Address}"/>
Note:
I have assumed that the public property name for the backing field private List<string> _address; is Address

Closing Caliburn Micro View from a UserControl Button?

I have created a UserControl name TitleBar, which is placed in every view.
The TitleBar.xaml contains a Button to close the Window in which it contain.
How can i close a Caliburn Window using that Button.
TitleBar UserControl
<UserControl x:Class="JIMS.Controls.TitleBar"
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">
<Grid Style="{StaticResource TitleBar}">
<Rectangle HorizontalAlignment="Stretch" Height="7" Margin="0,0,-5,0" VerticalAlignment="Top" Fill="{DynamicResource DefaultBrush}"></Rectangle>
<Grid HorizontalAlignment="Left" Margin="-10,-5,0,0" Name="Logo">
<TextBlock Name="txtTitle" Style="{StaticResource Title}">JIMS</TextBlock>
<Ellipse HorizontalAlignment="Right" Margin="0,0,5,0" Width="20" Height="20">
<Ellipse.Fill>
<VisualBrush Stretch="Fill" Visual="{StaticResource appbar_settings_white}" />
</Ellipse.Fill>
</Ellipse>
</Grid>
<Grid HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,-4,0">
<Button Name="btnClose" Style="{StaticResource ChromeButtonStyle}" Click="btnClose_Click" IsTabStop="False">
<TextBlock TextWrapping="Wrap" Text="r" FontFamily="Webdings" Foreground="#FF919191" FontSize="13.333" />
</Button>
</StackPanel>
</Grid>
</Grid>
</UserControl>
TitleBar Usage in a View
<UserControl xmlns:my="clr-namespace:JIMS.Controls;assembly=JIMS.Controls" x:Class="JIMS.Views.Stock.UnitView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Unit">
<Border Style="{StaticResource WindowBorderStyle}">
<StackPanel Orientation="Vertical">
<my:TitleBar Title="unit creation"/>
<StackPanel Visibility="{Binding ControlVisiblity}" Orientation="Horizontal" Margin="0,5,0,5">
<StackPanel Orientation="Vertical" Margin="10,0,0,0">
<Label>Short Name :</Label>
<Label>Unit Name :</Label>
</StackPanel>
<StackPanel Orientation="Vertical" Width="200" Margin="0,0,10,0">
<TextBox Name="txtShortName" Text="{Binding Path=UnitShort}"></TextBox>
<TextBox Name="txtUnitName" Text="{Binding Path=UnitName}"></TextBox>
</StackPanel>
</StackPanel>
<Expander Style="{StaticResource DisplayExpander}" IsExpanded="{Binding IsDisplayExpanded}" Header="display units">
<StackPanel Orientation="Horizontal" Margin="0,5,0,5" Visibility="{Binding DisplayVisiblity}">
<DataGrid AutoGenerateColumns="True" Height="200" MinWidth="300" ItemsSource="{Binding Display}"></DataGrid>
</StackPanel>
</Expander>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Name="SaveUnit" Style="{StaticResource MetroButton}">Save</Button>
</StackPanel>
</StackPanel>
</Border>
</UserControl>
In your TitleBar control define a RoutedEvent like this
public event RoutedEventHandler CloseClick
{
add { AddHandler(CloseClickEvent, value); }
remove { RemoveHandler(CloseClickEvent, value); }
}
public static readonly RoutedEvent CloseClickEvent = EventManager.RegisterRoutedEvent(
"CloseClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TitleBar));
void RaiseCloseClickEvent()
{
var newEventArgs = new RoutedEventArgs(TitleBar.CloseClickEvent);
RaiseEvent(newEventArgs);
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
RaiseCloseClickEvent();
}
And attach the btnClose_Click event handler to the btnClose control in your TitleBar
Now, when you use your TitleBar add an action like this
<my:TitleBar Title="This is the title">
<i:Interaction.Triggers>
<i:EventTrigger EventName="CloseClick">
<cal:ActionMessage MethodName="Close"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</my:TitleBar>
This will call the method Close on your viewmodel when the the CloseClickEvent is raised on the TitleBar.
For closing the window, you could derive your viewmodel from Screen and add the following snippet
public void Close()
{
TryClose();
}

Resources