Databinding WPF DatagridComboBoxColumns to MVVM not working

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.


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

eg

<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 :)


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));
    }

你正在绑定Collection的属性之一,这是你的ComboBox的ItemsSource,这是错误的。它应该像你应该有单独的Property作为SelectedValue上面,并将此属性绑定到ComboBox的SelectedValue。并且在此属性中,您可以获取并设置ComboBox.I的选定值希望这会有所帮助。


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>
链接地址: http://www.djcxy.com/p/56218.html

上一篇: WPF MVVM绑定错误

下一篇: 数据绑定WPF DatagridComboBoxColumns到MVVM无法正常工作