My question relates to how to initiate as action based on user mouse input.
I have a wpf window that displays information on an organization. Some organizations are vendors in which case vendor information is displayed in another row of the grid. I use the following trigger to display/hide that row. This works as desired.
<RowDefinition>
<RowDefinition.Style>
<Style
TargetType="RowDefinition">
<Setter Property="Height" Value="0" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsVendor}" Value="True">
<Setter Property="Height" Value="*" />
</DataTrigger>
</Style.Triggers>
</Style>
</RowDefinition.Style>
</RowDefinition>
For an organization which is not a vendor, the user can click on a button that adds vendor information and links that new information to the organization. However, that action does not cause the trigger to fire. Is there a way to do that? Or is there a different approach that would work better?
In your case, I will use a converter and bind the value of Height property.
<RowDefinition>
<RowDefinition.Style>
<Style TargetType="RowDefinition">
<Setter Property="Height" Value="{Binding IsVendor, Converter={StaticResource IsVendorConverter}}" />
</Style>
</RowDefinition.Style>
</RowDefinition>
The converter will receive your boolean value (IsVendor) and returns "0" if IsVendor is false and "*" if IsVendor is true.
public class IsVendorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var isVendor = (bool)value;
if (isVendor)
{
return "*";
}
return "0";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
You didn't share your xaml, but here is a sample used with a button (clicking one button changes the height of the other one).
<Window
x:Class="WpfApp1.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:local="clr-namespace:WpfApp1"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Window.Resources>
<local:IsVendorConverter x:Key="IsVendorConverter" />
</Window.Resources>
<StackPanel Orientation="Horizontal">
<Button Width="200" Height="{Binding IsVendor, Converter={StaticResource IsVendorConverter}}" />
<Button Width="200" Height="100" Click="Button_Click"/>
</StackPanel>
</Window>
Code Behind:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private bool _isVendor = false;
public bool IsVendor {
get { return _isVendor; }
set { _isVendor = value; OnPropertyRaised("IsVendor"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyRaised(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
IsVendor = true;
}
}
Related
I have a user control like this:
<UserControl>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<HyperlinkButton Grid.Row="0" />
<TextBlock Name="textblock" Grid.Row="1"
Text="{Binding dailyText, ElementName=userControl}">
</TextBlock>
</Grid>
</UserControl>
Nevertheless, I don't know, how can I set a style from mainwindow to user control? I have solved the problem to access to other properties like this:
public static readonly DependencyProperty MyContentProperty =
DependencyProperty.Register("MyContent", typeof(object), typeof(Day), null);
public object MyContent
{
get { return (object)GetValue(MyContentProperty ); }
set { SetValue(MyContentProperty , value); }
}
And then
<local:Day MyContent="Hello World" />
However, it doesn't work the style. There is no change in the sytle.
Thank you.
(Modification)
Below is a mainWindow part.
<Page.Resources>
<Style TargetType="TextBlock" x:Name="MyTextBlockStyle">
<Setter Property="Foreground" Value="Blue" />
<Setter Property="SelectionHighlightColor" Value="Red"/>
<Setter Property="FontSize" Value="10"/>
</Style>
</Page.Resources>
<local:Day MyStyle="{StaticResource MyTextBlockStyle}">
Behind-code part in userControl
public static readonly DependencyProperty MyStyleProperty =
DependencyProperty.Register("MyStyle", typeof(Style), typeof(Day), null);
public Style MyStyle
{
get { return (Style)GetValue(MyStyleProperty); }
set { SetValue(MyStyleProperty, value); }
}
You can use PropertyMetadata to initialise and set Style to your TextBlock. Like,
public Style MyStyle
{
get { return (Style)GetValue(MyStyleProperty); }
set { SetValue(MyStyleProperty, value); }
}
public static readonly DependencyProperty MyStyleProperty =
DependencyProperty.Register("MyStyle", typeof(Style), typeof(Day),
new PropertyMetadata(null, OnStyleChange));
private static void OnStyleChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as Day;
control.textblock.Style = (Style)e.NewValue
}
I would remove an item with button inside listview item and change color of ellipse with another button in listview item.
The class product code:
class Product
{
public string Name { get; set; }
public double Price { get; set; }
}
The xaml mainpage code:
<Page
x:Class="ListViewTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ListViewTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Loaded="Page_Loaded">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView x:Name="ListViewProducts"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
FontSize="18"
BorderThickness="0"
Width="600"
Height="800"
HorizontalAlignment="Center"
VerticalAlignment="Center"
ItemsSource="{Binding LineItems}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10">
<Grid HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0">
<Ellipse x:Name="EllipseColor" HorizontalAlignment="Left" Height="20" Stroke="Black" VerticalAlignment="Top" Width="20" StrokeThickness="1"/>
</Grid>
<TextBlock Text="{Binding Name}" Margin="5,0,0,0"/>
<TextBlock Text="{Binding Price}" Margin="5,0,0,0"/>
<Button x:Name="btnRemove" Click="btnRemove_Click" Height="20" Width="60" Margin="5"/>
<Button x:Name="btnChangeColor" Click="btnChangeColor_Click" Height="20" Width="60" Margin="5"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
The code behind of mainpage:
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
ObservableCollection<Product> _listProduct = new ObservableCollection<Product>();
_listProduct = new ObservableCollection<Product>
{
new Product
{
Name = "Phone",
Price = 100
},
new Product
{
Name = "TV",
Price = 120
},
new Product
{
Name = "Computer",
Price = 80
},
new Product
{
Name = "Laptop",
Price = 250
},
new Product
{
Name = "Tablet",
Price = 150
},
new Product
{
Name = "Monitor",
Price = 200
},
};
ListViewProducts.ItemsSource = _listProduct;
}
private void btnRemove_Click(object sender, RoutedEventArgs e)
{
// Code to remove item
}
private void btnChangeColor_Click(object sender, RoutedEventArgs e)
{
// Code to color EllipseColor
}
}
With btnRemove i would delete listview item and with btnChangeColor i would color red the fill of EllipseColor, in btnChangeColor_Click i would the index of item.
Thanks in advance.
It looks to me like you've got several issues. First off is that you're setting your ListView source via binding to an apparently non-existent collection, as well as setting it in C#. You should move it to using a proper binding. For example, in MainPage.xaml.cs:
private ObservableCollection<Product> _products = new ObservableCollection<Product>();
public ObservableCollection<Product> Products { get => _products; set => _products = value; }
And then bind to it:
<ListView ItemsSource={x:Bind Products, Mode=OneWay} />
Then, in btnRemove_Click, you can just remove the item from the collection:
var product = (sender as Button).DataContext as Product;
Products.Remove(product);
As for coloring the Ellipse, you shouldn't really do that in C#. Instead, you should have a Status property on your Product class, and then change that property.
First off, you'll need to make sure your property changes fire notifications.
public class Product : INotifyPropertyChanged
{
private string _status;
public string Status
{
get => _status;
set
{
_status = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Status)));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
Then change the property.
var product = (sender as Button).DataContext as Product;
product.Status = "invalid";
Then in your XAML, use a binding converter to change the Ellipse's Fill property based on the status. E.g.
using System;
using Windows.UI;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
public class StatusConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language) =>
new SolidColorBrush(value.ToString() == "invalid" ? Colors.Red : Colors.Gray);
public object ConvertBack(object value, Type targetType, object parameter, string language) =>
throw new NotImplementedException();
}
You'll then need to add the converter to your resources.
<Page...>
<Page.Resources>
<locationofyourconverter:StatusConverter x:Key="StatusConverter" />
</Page.Resources>
...
<Ellipse Fill={Binding Status, Mode=OneWay, Converter={StaticResource StatusConverter}} />
I have a listview that has the selectedIndex binded to the ViewModel.
When the ViewModel changes the selectedIndex the listview selects the new item, unfortunately it does not focus on it and if a lot items are present in the list then this is annoying for the user.
How can I change to focus to the selectedItem using XAML or at least respecting MVVM.
<ListView ItemsSource="{Binding allTags}" ItemTemplate="{StaticResource listTemplate}"
SelectedIndex="{Binding selectedIndex}">
</ListView>
You could use an attached behaviour to focus the TextBox:
public static class FocusExtension
{
public static bool GetIsFocused(TextBox textBox)
{
return (bool)textBox.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(TextBox textBox, bool value)
{
textBox.SetValue(IsFocusedProperty, value);
}
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached("IsFocused", typeof(bool), typeof(FocusExtension),
new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
private static void OnIsFocusedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextBox textBox = d as TextBox;
if ((bool)e.NewValue)
{
textBox.Dispatcher.BeginInvoke(new Action(()=>
{
Keyboard.Focus(textBox);
}), DispatcherPriority.Background);
}
}
}
View:
<Window.DataContext>
<local:TestWindowViewModel></local:TestWindowViewModel>
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="template">
<TextBox x:Name="listItemTextBox">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=ListViewItem}}" Value="True">
<Setter Property="local:FocusExtension.IsFocused" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ListView ItemsSource="{Binding myList}" ItemTemplate="{StaticResource template}" SelectedIndex="{Binding SelectedIndex}"></ListView>
</StackPanel>
View Model:
public class TestWindowViewModel : INotifyPropertyChanged
{
public List<string> myList { get; set; }
private int _selectedIndex;
public int SelectedIndex
{
get { return _selectedIndex; }
set { _selectedIndex = value; }
}
public TestWindowViewModel()
{
myList = new List<string> { "one", "two", "three" };
SelectedIndex = 1;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
I'm pretty new to MVVM so i assume this is basics. It's a Windows 8.1 app with MVVM light and a Sqlite DB.
I've got a page that contain 4 States. Each State contain a GridView where you can select an item to set a bound property. On the SelectionChanged I go to the next State.
Here's the GridView's xaml :
<GridView Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Essences}" SelectedItem="{Binding SelectedEssense,Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="EssenceGridView" Opacity="0" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="SelectionChanged">
<Core:GoToStateAction StateName="Diametre"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<GridView.ItemTemplate>
<DataTemplate >
<Grid Width="250" Height="80">
<TextBlock Text="{Binding Trigramme}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
The StoryBoards that change States are just Opacity changing.
Now I want to be able to totaly skip one State, because the user want to be able to use some defaults properties (so he don't have to select the same one all the time)
So, if the default property is set in my ViewModel, I want to able to skip one state.
What is the best approach to achieve this in MVVM ?
Edit : With the help of the link of Depechie, I successfully bind my VisualState to property in my ViewModel. I had to update the code because it was for Windows phone 8 and i'm working with Windows 8.1 !!
Here the updated class :
BindVisualStateBehaviorHandler.cs
class BindVisualStateBehaviorHandler : Behavior<FrameworkElement>
{
//
// Dependency property "StateName" that you can bind in Blend.
// Bind this to the enumeration that controls the visual state.
//
public static DependencyProperty StateNameProperty = DependencyProperty.Register(
"StateName",
typeof(string),
typeof(BindVisualStateBehaviorHandler),
new PropertyMetadata(null, StateNamePropertyChanged));
public string StateName
{
get { return (string)GetValue(StateNameProperty); }
set { SetValue(StateNameProperty, value); }
}
//
// When the StateName property changes, switch to the
// new visual state, and play transition animations.
//
private static void StateNamePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
((BindVisualStateBehaviorHandler)obj).UpdateVisualState(
(string)args.NewValue,
useTransitions: true);
}
//
// When the behavior is first attached, go to the visual state,
// but don't play any animations.
//
protected override void OnAttached()
{
UpdateVisualState(
StateName,
useTransitions: false);
base.OnAttached();
}
private void UpdateVisualState(string visualState, bool useTransitions)
{
if (AssociatedObject != null)
{
if (VisualStateUtilities.FindNearestStatefulControl(base.AssociatedObject as FrameworkElement) != null)
{
VisualStateUtilities.GoToState(
VisualStateUtilities.FindNearestStatefulControl(base.AssociatedObject as FrameworkElement),
visualState,
useTransitions);
}
}
}
}
I had to use my own Behavior cuz it was not présent in Microsoft.Xaml.Interactivity
Behavior.cs
public abstract class Behavior<T> : DependencyObject, IBehavior where T : DependencyObject
{
//http://reflectionit.nl/Blog/2013/windows-8-xaml-tips-creating-blend-behaviors
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
public T AssociatedObject { get; set; }
protected virtual void OnAttached()
{
}
protected virtual void OnDetaching()
{
}
public void Attach(Windows.UI.Xaml.DependencyObject associatedObject)
{
this.AssociatedObject = (T)associatedObject;
OnAttached();
}
public void Detach()
{
OnDetaching();
}
DependencyObject IBehavior.AssociatedObject
{
get { return this.AssociatedObject; }
}
}
Then in my View :
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AppStates" >
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.2"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="SaisieTige" >
...
<VisualState x:Name="Diametre">
...
</VisualState>
<VisualState x:Name="Hauteur">
...
</VisualState>
<VisualState x:Name="Resume">
...
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Interactivity:Interaction.Behaviors>
<Behavior:BindVisualStateBehaviorHandler x:Name="AppStateBehavior" StateName="{Binding StateHandler.AppState,Mode=TwoWay}"></Behavior:BindVisualStateBehaviorHandler>
<Core:EventTriggerBehavior EventName="Loaded">
<Core:InvokeCommandAction Command="{Binding SelectEssenceOrNotCommand}"></Core:InvokeCommandAction>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
I have to call the RaisePropertyCHange each time i change the State :
StateHandler.SetAppState(AppStates.SaisieTige);
RaisePropertyChanged("StateHandler");
ANd Now it's working, thx a lot guys !!!
I need to track the Current Column Name and Sort Direction In WPF MVVM DataGrid. I know how to do it in code behind. Plase see the code as follows:
private void columnHeader_Click(object sender, RoutedEventArgs e)
{
var columnHeader = sender as DataGridColumnHeader;
if (columnHeader != null)
{
columnName = ((DataGridColumnHeader)sender).Content.ToString();
ListSortDirection sortDirection = (((DataGridColumnHeader)sender).SortDirection != ListSortDirection.Ascending) ?
ListSortDirection.Ascending : ListSortDirection.Descending;
txb1.Text = columnName;
txb2.Text = sortDirection.ToString();
}
}
However, I am blocked in MVVM. In the View Model, I wrote codes in method sort() in SortCommand, but they did not work. I would appreciate if any one can help. Below are three files.
1) Xaml
<Window x:Class="SortSampleMVVM1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:se="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid x:Name="Test"
ItemsSource="{Binding}"
AutoGenerateColumns="False" >
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Command"
Value="{Binding SortCommand}"/>
<Setter Property="CommandParameter"
Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid Name="dataGrid1" AutoGenerateColumns="False" ItemsSource="{Binding ViewSource.View}" >
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding ID }"
SortDirection="Descending" />
<DataGridTextColumn Header="firstName" Binding="{Binding firstName}"/>
<DataGridTextColumn Header="lastName" Binding="{Binding lastName}"/>
</DataGrid.Columns>
</DataGrid>
<Label Content="Column Name" HorizontalAlignment="Left" Margin="100,166,0,0" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="250,169,0,0" TextWrapping="Wrap" Name="txb1" Text="{Binding ColumnName}" VerticalAlignment="Top" Width="150" />
<Label Content="Sorting direction" HorizontalAlignment="Left" Margin="100,229,0,0" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="250,232,0,0" TextWrapping="Wrap" Name="txb2" Text="{Binding SortDirection}" VerticalAlignment="Top" Width="150" />
<Button Content="Refresh" Name="btnRefresh1" HorizontalAlignment="Left" Margin="140,273,0,0" VerticalAlignment="Top" Width="75" Command="{Binding Refresh1Command}" />
<Button Content="Refresh Keep Sort" Name="btnRefresh2" HorizontalAlignment="Left" Margin="282,273,0,0" VerticalAlignment="Top" Width="125" Command="{Binding Refresh2Command}" />
</Grid>
</Window>
2) Code behind
using System.Windows;**strong text**
using System.Collections.ObjectModel;
using System.Collections.Generic;
namespace SortSampleMVVM1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new SortViewModel();
}
}
}
3) View Model
using System;
using System.ComponentModel;
using System.Windows.Input;
using System.Windows.Controls.Primitives;
using System.Windows;
using System.Windows.Data;
using System.Collections.ObjectModel;
namespace SortSampleMVVM1
{
class SortViewModel: INotifyPropertyChanged
{
public CollectionViewSource ViewSource { get; set; }
public ObservableCollection<MyData> Collection {get; set;}
private string _columnName;
private ListSortDirection _sortDirection;
private ICommand _sortCommand;
private ICommand _refresh1Command;
private ICommand _refresh2Command;
public SortViewModel ()
{
this.Collection = new ObservableCollection<MyData>();
Collection.Add(new MyData(1, "David", "Lee"));
Collection.Add(new MyData(2, "John", "kim"));
Collection.Add(new MyData(3, "Michael", "Wadsworth"));
Collection.Add(new MyData(4, "Chris", "Smith"));
Collection.Add(new MyData(5, "Peter", "Chen"));
Collection.Add(new MyData(6, "Jonas", "Zhang"));
this.ViewSource = new CollectionViewSource();
ViewSource.Source = this.Collection;
}
public event PropertyChangedEventHandler PropertyChanged;
public string ColumnName
{
get { return _columnName; }
set
{
_columnName = value;
OnPropertyChanged("ColumnName");
}
}
public ListSortDirection SortDirection
{
get { return _sortDirection; }
set
{
_sortDirection = value;
OnPropertyChanged("SortDirection");
}
}
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
#region SortCommand
public ICommand SortCommand
{
get
{
if (_sortCommand == null)
{
_sortCommand = new RelayCommand(param => this.sort(),
null);
}
return _sortCommand;
}
}
private void sort()
{
//var columnHeader = (object)sender as DataGridColumnHeader;
//if (columnHeader != null)
//{
// _columnName = ViewSource.GetValuecolumnName ((DataGridColumnHeader)sender).Content.ToString();
// ListSortDirection sortDirection = (((DataGridColumnHeader)sender).SortDirection != ListSortDirection.Ascending) ?
// ListSortDirection.Ascending : ListSortDirection.Descending;
//}
}
#endregion
#region Refresh1Command
public ICommand Refresh1Command
{
get
{
if (_refresh1Command == null)
{
_refresh1Command = new RelayCommand(param => this.Refresh1(),
null);
}
return _refresh1Command;
}
}
private void Refresh1()
{
ViewSource.SortDescriptions.Clear();
_columnName = "firstName";
_sortDirection = ListSortDirection.Descending;
ViewSource.SortDescriptions.Add(new SortDescription(_columnName, _sortDirection));
ViewSource.View.Refresh();
}
#endregion
#region Refresh2Command
public ICommand Refresh2Command
{
get
{
if (_refresh2Command == null)
{
_refresh2Command = new RelayCommand(param => this.Refresh2(),
null);
}
return _refresh2Command;
}
}
private void Refresh2()
{
ViewSource.SortDescriptions.Clear();
ViewSource.SortDescriptions.Add(new SortDescription(_columnName, _sortDirection));
ViewSource.View.Refresh();
}
#endregion
}
}
You can use following styling to get the column header.
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Command"
Value="{Binding DataContext.MyCommand}"/>
<Setter Property="CommandParameter"
Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.ColumnHeaderStyle>
You have to create the Command 'MyCommand' in your view model. then as the parameter of your execute method you will get column header name.