0
votes

It is possible in a GridView to manualy bind column ItemsSource to Enum with selectedItemBinding path set to to property of DataGrid.ItemsSource like this:

<Window.Resources>
<ObjectDataProvider x:Key="DirectionEnum"
                    MethodName="GetValues"
                    ObjectType="{x:Type core:Enum}">
        <ObjectDataProvider.MethodParameters>
                <x:Type Type="local:Direction"/>
        </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>

...

<DataGrid x:Name="DgvZlecNag" 
    AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridComboBoxColumn Header="Column0"
                 SelectedItemBinding="{Binding Direction}"
                 ItemsSource="{Binding Source={StaticResource DirectionEnum}}"/>

...

public enum Direction 
{
    Def = 0,
    Imp = 1,
    Exp = 2,
}

...

public MainWindow()
    {

        InitializeComponent();
        _orders = new ObservableCollection<ZlecNag>()
        {
            new ZlecNag() {
                Id = 1,
                Direction = Direction.Imp
                }
        }
    DgvZlecNag.ItemsSource = zlecenia;
    }

What i'm trying to do is to similarly bind column to ObservableCollection but it doesn't quite work. I tried to do this with staticResource in column1, which works but doesn't show value initialy set, and to local observableCollection in column2, which shows the initial value but value of binded propery doesn't change with selecting new item in combobox. Column3 is just to show if the binded property changes.

<Window x:Class="ZleceniaTransportowe2.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ZleceniaTransportowe2"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:core="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="500" Width="1200"
        >
<Window.Resources>
       <ObjectDataProvider x:Key="Clients"
                            MethodName="GetData"
                            ObjectType="{x:Type local:CollectionData}"
                            >
            <ObjectDataProvider.MethodParameters>
                <x:Type Type="local:CollectionData"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
        <local:IfNullConverter x:Key="IfNullConverter"/>
</Window.Resources>
        <DataGrid x:Name="DgvZlecNag" 
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Id"
                                    Binding="{Binding Id, Mode=OneWay}"/>
                <DataGridComboBoxColumn Header="Column1"
                                        SelectedItemBinding="{Binding Path=Client, Mode=TwoWay}"
                                        ItemsSource="{Binding Source={StaticResource Clients}}"
                                        SelectedValuePath="Akronim"  DisplayMemberPath="Akronim"/>
                <DataGridTemplateColumn Header="Column2">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox SelectedValue="{Binding Client.Akronim, Mode=TwoWay}"
                                      DisplayMemberPath="Akronim"  SelectedValuePath="Akronim" SelectedItem="Client"
                                      ItemsSource= "{Binding Clients, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window }}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Header="column3"
                                    Binding="{Binding Client.Akronim, Mode=OneWay}"/>
            </DataGrid.Columns>

        </DataGrid>
</Window>

the code behind:

namespace ZleceniaTransportowe2
{
    public partial class MainWindow: Window
    private ObservableCollection<ZlecNag> _orders;

    public ObservableCollection<Client> Clients {get;} = new ObservableCollection<Client>()
        {
            new Client()
            {
                Akronim = "Seifert",
            },
            new Client()
            {
                Akronim = "Cenergo",
            }
        };

        public MainWindow()
        {
            InitializeComponent();
            _orders = new ObservableCollection<ZlecNag>()
            {
                new ZlecNag() {
                    Id = 1,
                    Client = Clients.First(),

                },
               new ZlecNag() {
                    Id = 1,
                    Client = Clients[1],
                   }
                };
             DgvZlecNag.ItemsSource = _orders;
        }
    }
}

...

public class ZlecNag : INotifyPropertyChanged
{

    private Direction _direction;
    private Client _client;

    public Direction Direction
    {
        get { return _client; }
        set
        {
            _direction= value;
            OnPropertyChanged();
        }
    }

    public Client Client
    {
        get { return _client; }
        set
        {
            _client = value;
            OnPropertyChanged();
        }
    }
        public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

...

public class Client : INotifyPropertyChanged

{
    private int _gidNumer;
    private string _akronim;

    public int GidNumer
    {
        get { return _gidNumer; }
        set
        {
            _gidNumer = value;
            OnPropertyChanged();
        }
    }

    public string Akronim

    {
        get { return _akronim; }
        set
        {
            _akronim = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

...

Class with data for objectDataProvider for column2:

public class CollectionData
{
    public static ObservableCollection<Client> GetData(Type type = null)
    {
        var clients = new ObservableCollection<Client>()
        {
            new Client()
            {
                Akronim = "Seifert",
                GidNumer = 4654
            },
              new Kontrahent()
            {
                Akronim = "Cenergo",
                GidNumer = 4656
            }
        };
        return clients;
    }
}

Please help, i out of ideas how to fix this.

2
Please make a small workable application which can be tested conceptually, something like a small model of bigger app. - AnjumSKhan
Good idea @AnjumSKhan, i've added link to zip file with my project. - mdziadowiec
please post that link as a comment. remove the dropbox link from the question as it does not follow SO guidelines. - AnjumSKhan

2 Answers

1
votes

You are not using Binding in column2, instead you have written SelectedItem="Client" , please consider binding in SelectedItem.

0
votes

Apparently it can be accomplished as well without the template column containing combobox. It looks nicer because cell doesn't look like a combobox untill it's been clicked, so it doesn't stand out from the other DataGrid cells.

Based on the answer https://stackoverflow.com/a/5409984/2458980

<DataGridComboBoxColumn SelectedValueBinding="{Binding Contractor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                        DisplayMemberPath="Acronym">     
    <DataGridComboBoxColumn.ElementStyle>
         <Style TargetType="{x:Type ComboBox}">
             <Setter Property="ItemsSource" Value="{Binding Path=Contractors, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
         </Style>
     </DataGridComboBoxColumn.ElementStyle>
     <DataGridComboBoxColumn.EditingElementStyle>
         <Style TargetType="{x:Type ComboBox}">
             <Setter Property="ItemsSource" Value="{Binding Path=Contractors, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
         </Style>
     </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>