1
votes

Following the answers in these 2:

Using WPF DataGridComboBoxColumn with MVVM - Binding to Property in ViewModel

Binding a WPF DataGridComboBoxColumn with MVVM

1) I can't get the values in the ObservableCollections to be set when a selection in the combobox is made.

The comboboxes are being populated with the List from the ViewModel but values are not being set.

Code:

<DataGrid ItemsSource="{Binding SidValues1through5, Mode=TwoWay}"                                  
     AutoGenerateColumns="False"
     Grid.Row="1"   
     Margin="5"
     VerticalAlignment="Top"
     HorizontalAlignment="Center">
     <DataGrid.Columns>
           <DataGridComboBoxColumn Header="1"
                                   Width="100"
                                   SelectedValueBinding="{Binding Value1}"
                                   SelectedValuePath="Value1">
                                    <DataGridComboBoxColumn.ElementStyle>
                                        <Style TargetType="ComboBox">
                                            <Setter Property="ItemsSource"
                                                    Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.AvailableSids}" />
                                        </Style>
                                    </DataGridComboBoxColumn.ElementStyle>
                                    <DataGridComboBoxColumn.EditingElementStyle>
                                        <Style TargetType="ComboBox">
                                            <Setter Property="ItemsSource"
                                                    Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.AvailableSids}" />
                                        </Style>
                                    </DataGridComboBoxColumn.EditingElementStyle>
                                </DataGridComboBoxColumn>

ViewModel interface (I've debugged and I am connected to the ViewModel, other controls on the view are bound correctly:

ETA: BindableCollection inherits from ObservableCollection it's a Caliburn.Micro type.

public interface ICustomSIDViewModel : IScreen
{
    BindableCollection<SidValues> SidValues1through5 { get; set; }
    BindableCollection<SidValues> SidValues6through10 { get; set; }

    IList<string> AvailableSids { get; }
}

public class SidValues
{
    public string Value1 { get; set; }
    public string Value2 { get; set; }
    public string Value3 { get; set; }
    public string Value4 { get; set; }
    public string Value5 { get; set; }
}

2) Once I resolve this is there a cleaner way to have all the columns inherit this one set of DataGridComboBoxColumn.ElementStyle and DataGridComboBoxColumn.EditingElementStyle?

Reason I ask is there are 10 columns all will have the same combobox list.

3

3 Answers

0
votes

For the first question - it's WPF so you shouldn't need to use Mode=TwoWay on your bindings, but try that for starters just in case.

The default for WPF afaik is TwoWay, but not for SL. Try it anyway.

For the second question, just declare a nested style in your resource dictionary. Nested styles apply to child elements of the target control

e.g.

<Style x:Key="DataGridComboBoxStyle" TargetType="DataGrid">
    <!-- Nested -->
    <Style.Resources>
            <Style TargetType="ComboBox">
                <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.AvailableSids}" />
            </Style>
    </Style.Resources>
</Style>

You could also apply a style to the entire control and nest this style in that style :)

0
votes
SelectedValueBinding="{Binding SelectedValue, Mode=TwoWay}"
                                       SelectedValuePath="Value1">

private string selectedValue;
    public string SelectedValue 
    {
        get
        {
            return selectedValue;
        }
        set
        {
            selectedValue = value;
            Notify("SelectedValue");
        } 
    }

    private void Notify(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

You are binding one of the property of Collection that is your ComboBox's ItemsSource ,thats wrong .It should be like you should have separate Property as SelectedValue above and bind this Property to the SelectedValue of ComboBox.And In this Property You can get and set the Selected value of the ComboBox.I hope this will help.

0
votes

What I finally had to go with to work and move on with the project was a ListView with a GridView inside. Not exactly the same but looks similar.

I'm still curious on how to get a DataGrid to actually work with MVVM and Caliburn.Micro, I tried every example I found and couldn't get the combobox selection to update anything on the VM.

Here's my solution:

<ListView.View>
    <GridView>                                    
        <GridViewColumn Header="1"
                       Width="100">
            <GridViewColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding Path=DataContext.AvailableSids,
                                        RelativeSource={RelativeSource FindAncestor, 
                                        AncestorType={x:Type UserControl}}}"
                              SelectedItem="{Binding Path=Value1, Mode=TwoWay, 
                                              UpdateSourceTrigger=PropertyChanged}" />
                </DataTemplate>
            </GridViewColumn.CellTemplate>
        </GridViewColumn>
    </GridView>  
</ListView.View>