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.

```text
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

```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
```xml
<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.

```xml
<DataGrid.Resources>
    <!--DataGridのItemSourceとは別のアイテムをBindするために必要-->
    <services:BindingProxy x:Key="Proxy" Data="{Binding}"/>
</DataGrid.Resources>
```

Example: incorporating it into a DataGrid

▼SampleView.xaml
```xml
<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
```xml
<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
```cs
private Visibility _workerNameVisibility = Visibility.Visible;
public Visibility WorkerNameVisibility
{
    get { return _workerNameVisibility; }
    set { SetProperty(ref _workerNameVisibility, value); }
}
```

That's it.
