Siegfried.V
Siegfried.V

Reputation: 1595

GridView ComboBox - Bind selected element property

EDIT : Working better, but still not perfect :

SelectedFace has been set as ComboElement (still couldn't manage to do the job without this additional parameter).

Still not working : When I create a new Tool, SelectedFace is updated correctly, but if I want to edit an existing one, no Update is made(no binding).

End Edit

I have a GridView, in which there is a ComboBox to select on which face each tool located.

I cannot manage to bind the selected value to my object property.

Here are the properties as declared in my Tool object :

    private long face = 0;
    public long Face
    {
        get { return face; }
        set
        {
            this.face = value;
            this.NotifyPropertyChanged("Face");
        }
    }
    private ComboElement selectedFace;
    public ComboElement SelectedFace
    {
        get { return selectedFace; }
        set
        {
            this.selectedFace = value;
            this.Face = value.MyInt;
            this.NotifyPropertyChanged("SelectedFace");
        }
    }

    private ObservableCollection<ComboElement> comboFaceSlot=new ObservableCollection<ComboElement> { new ComboElement { MyInt = 0, MyString = "Web" }, new ComboElement { MyInt = 1, MyString = "Top" }, new ComboElement { MyInt = 2, MyString = "Bottom" }, new ComboElement { MyInt = 3, MyString = "Back" } };
    public ObservableCollection<ComboElement> ComboFaceSlot
    {
        get { return comboFaceSlot; }
        set
        {
            this.comboFaceSlot = value;
            this.NotifyPropertyChanged("ComboFaceSlot");
        }
    }

Nota : At the beginning I had not the SelectedFace property, I added it thinking this would solve my problem, but it didn't.

And XAML is as following :

<DataGrid Grid.Row="1" Margin="5" BorderBrush="{StaticResource WindowBorderColor}" BorderThickness="3" Width="Auto"  ItemsSource="{Binding Path=ListTools}" AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="True" HorizontalAlignment="Center">
    <DataGrid.Columns>
        <DataGridTextColumn Header="{x:Static p:Resources.Length}" Binding="{Binding Path=Longueur}" Width="100" />
        <DataGridTextColumn Header="{x:Static p:Resources.Diameter}" Binding="{Binding Path=Diameter}" Width="100" />

        <DataGridTemplateColumn Header="{x:Static p:Resources.Face}">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding ComboFaceSlot}" DisplayMemberPath="MyString" SelectedItem="{Binding SelectedFace}" Width="100" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="{x:Static p:Resources.Angle}" Binding="{Binding Path=Angle}" Width="100" />
    </DataGrid.Columns>
</DataGrid>

Also forgot, my ComboElement I use for all Comboboxes of my project :

public class ComboElement
{
    private long myInt=-1;
    public long MyInt
    {
        get { return myInt; }
        set { myInt = value; }
    }
    private string myString="";
    public string MyString
    {
        get { return myString; }
        set { myString = value; }
    }
    public ComboElement()
    {

    }
    public ComboElement(long id, string name)
    {
        this.myInt = id;
        this.MyString = name;
    }

}

Edit : My ViewModel

private ObservableCollection<Tool> listTool = new ObservableCollection<Tool>();
public ObservableCollection<Tool> ListTool
{
    get { return listTool; }
    set
    {
        this.listTool = value;
        NotifyPropertyChanged("ListTool");
    }
}
private Machine cnc = new Machine();
public Machine CNC
{
   get { return cnc; }
   set { this.cnc = value;NotifyPropertyChanged("CNC"); }
}
public TableTools(Machine cnc)
{
    InitializeComponent();
    this.CNC = cnc;
    foreach(Tool slot in CNC.ListTool)
    {
        this.ListTool.Add(slot);
    }

    DataContext = this;
}

It lists a list of Tools, and I want to say on which face each element is located. But for now something is going wrong, I tried to use several properties of my ComboBox as SelectedItem, SelectedValue, SelectedValuePath, but until now didn't manage to solve it. Ideally, I would like to delete "SelectedFace" element, and use only "Face" property.

Upvotes: 0

Views: 85

Answers (1)

IvanJazz
IvanJazz

Reputation: 773

You need to specify the Tool class like such in your question.

The root cause is not specifying the correct SelectedValuePath of your ComboElement object to be mapped to your Tool object's Face property as the SelectedValue.

Tool Class

public class Tool
{
    private ObservableCollection<ComboElement> comboFaceSlot = new ObservableCollection<ComboElement> { new ComboElement { MyInt = 0, MyString = "Web" }, new ComboElement { MyInt = 1, MyString = "Top" }, new ComboElement { MyInt = 2, MyString = "Bottom" }, new ComboElement { MyInt = 3, MyString = "Back" } };
    public ObservableCollection<ComboElement> ComboFaceSlot
    {
        get { return comboFaceSlot; }
        set
        {
            this.comboFaceSlot = value;
            this.NotifyPropertyChanged("ComboFaceSlot");
        }
    }

    private long face = 0;
    public long Face
    {
        get { return face; }
        set
        {
           this.face = value;
           this.NotifyPropertyChanged("Face");
        }
    }
}

ToolWindow View

<DataGrid Grid.Row="1" Margin="5" BorderBrush="{StaticResource WindowBorderColor}" BorderThickness="3" Width="Auto"  ItemsSource="{Binding Path=ListTools}" AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="True" HorizontalAlignment="Center">
    <DataGrid.Columns>
        <DataGridTextColumn Header="{x:Static p:Resources.Length}" Binding="{Binding Path=Longueur}" Width="100" />
        <DataGridTextColumn Header="{x:Static p:Resources.Diameter}" Binding="{Binding Path=Diameter}" Width="100" />

        <DataGridTemplateColumn Header="{x:Static p:Resources.Face}">
            <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ComboBox ItemsSource="{Binding ComboFaceSlot}"  
                          DisplayMemberPath="MyString" 
                          SelectedValuePath="MyInt"
                          SelectedValue="{Binding Face, UpdateSourceTrigger=PropertyChanged}" Width="100" />
            </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    <DataGridTextColumn Header="{x:Static p:Resources.Angle}" Binding="{Binding Path=Angle}" Width="100" />
</DataGrid.Columns>

Upvotes: 2

Related Questions