C# | WPF Prism DataGrid Column Visibility Binding
How to bind a DataGrid column's Visibility in C# WPF Prism
I'll explain how to bind the Visibility of a DataGrid column using WPF Prism in C#.
For example, when data-binding a combo box (or its options) to a column inside a DataGrid, using RelativeSource FindAncestor is one approach you might consider.
However, when data-binding to a DataGrid column's Visibility, the RelativeSource approach doesn't work.
So, we handle it by creating a class that lets us reference the ViewModel.
Target Files (Example)
The files you need to code are A through C below.
WPF/
|-Services/
| |-BindingProxy.cs ・・・A
|
|-Views/
| |-SampleView.xaml ・・・B
|
|-ViewModels/
| |-SampleViewModel.cs ・・・C
BindingProxy.cs ・・・A
Normally, when you use ItemsSource, each element of the bound collection becomes the DataContext, so inside a DataGrid you can't bind to anything other than ItemsSource.
※DataContext: the target of a Binding
To work around this, we prepare a "BindingProxy" class that lets controls inside the DataGrid access the ViewModel's properties directly.
▼BindingProxy.cs
using System.Windows;
namespace Template2.WPF.Services
{
/// <summary>
/// ViewModelのバインディングソースの代理として働くクラスです。
/// </summary>
public class BindingProxy : Freezable
{
/// <summary>
/// Freezableオブジェクトのインスタンスを生成します。
/// </summary>
/// <returns></returns>
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
/// <summary>
/// 間をとりもつプロパティ
/// データバインドした場合は、このプロパティがViewModelの代わりになる。
/// </summary>
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
/// <summary>
/// Data の依存関係プロパティ定義
/// </summary>
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
}
SampleView.xaml ・・・B
①Add a reference to the local class in the View's xaml
Add a namespace reference to the BindingProxy class on the Window or UserControl element.
Example: if the namespace of BindingProxy.cs is Template2.WPF.Services
xmlns:services="clr-namespace:Template2.WPF.Services"
▼SampleView.xaml
<UserControl x:Class="Template2.WPF.Views.Sample002View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
Background="{StaticResource backgroundColor}"
xmlns:services="clr-namespace:Template2.WPF.Services"
>
②Add a BindingProxy reference to the DataGrid's resources
Add the code below to make BindingProxy usable inside the DataGrid.
<DataGrid.Resources>
<!--DataGridのItemSourceとは別のアイテムをBindするために必要-->
<services:BindingProxy x:Key="Proxy" Data="{Binding}"/>
</DataGrid.Resources>
Example: incorporating it into a DataGrid
▼SampleView.xaml
<DataGrid Style="{StaticResource commonDataGrid}"
ItemsSource="{Binding WorkerMstEntities}"
SelectedItem="{Binding WorkerMstEntitiesSlectedItem}"
VerticalAlignment="Top"
HorizontalAlignment="Left"
IsReadOnly="False"
CanUserAddRows="False"
Cursor="Hand">
<DataGrid.Resources>
<!--DataGridのItemSourceとは別のアイテムをBindするために必要-->
<services:BindingProxy x:Key="Proxy" Data="{Binding}"/>
</DataGrid.Resources>
(省略)
③Bind the DataGrid column's Visibility
Add Visibility to the DataGrid's Column element.
Key points
- Write
Binding: Data.XXX - Write
Source: StaticResource
▼SampleView.xaml
<DataGrid.Columns>
<!-- カラムのVisibilityは、BindingProxyクラスを利用してViewModelのプロパティを参照する必要有り -->
<materialDesign:DataGridTextColumn Header="作業者名称"
Binding="{Binding WorkerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding Data.WorkerNameVisibility, Source={StaticResource Proxy}}">
(省略)
SampleViewModel.cs ・・・C
④Prepare a property on the ViewModel for the Visibility binding
Just like the usual way of data-binding a property in WPF Prism, add a property (and its backing private field) whose name matches what Visibility is bound to.
▼SampleViewModel.cs
private Visibility _workerNameVisibility = Visibility.Visible;
public Visibility WorkerNameVisibility
{
get { return _workerNameVisibility; }
set { SetProperty(ref _workerNameVisibility, value); }
}
That's it.
Related plants
More Tech articles →C# | How to call a MainWindow method from a partial View in WPF Prism
In WPF Prism, you can call a method on the Main Window from a partial view. Using Prism's Event Aggregator avoids direct references between view models and makes it easy to handle events raised within the application.
#csharp#wpf#prismC# | How to call a View method in ContentRegion from MainWindow in WPF Prism
In WPF Prism, an application may consist of a main window and a set of regions contained within it, hosting views and view models that communicate with each other. This explains how to call a method on a view or view model in the Content Region from the Main Window.
#csharp#wpf#prismC# | How to implement video (MediaElement) in WPF Prism using the MVVM pattern
How to implement video playback (MediaElement.Play()) in WPF Prism using the MVVM pattern.
#csharp#wpf#prism