0

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.

mdziadowiec
  • 396
  • 3
  • 10

2 Answers2

1

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

AnjumSKhan
  • 9,647
  • 1
  • 26
  • 38
  • I have change it to `SelectedItem="{Binding Path=Contractor, Mode=TwoWay}"` but it didn't help. – mdziadowiec Dec 12 '15 at 15:48
  • also apply UpdateSourceTrigger=PropertyChanged – AnjumSKhan Dec 12 '15 at 15:50
  • It's working now, thanks a lot @AnjumSKhan I'm wondering why i had to specifically apply this property, usually it wasn't necessary. – mdziadowiec Dec 12 '15 at 15:57
  • 1
    thats because the default values are different for different controls. – AnjumSKhan Dec 12 '15 at 15:58
  • @mdziadowiec ... and try to see the actual problem and how you described it. advice : here you should have made a small independent application using DataGrid, ComboBox in a column, a similar datasource etc, and check it. – AnjumSKhan Dec 12 '15 at 16:57
0

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>
Community
  • 1
  • 1
mdziadowiec
  • 396
  • 3
  • 10