简体   繁体   English

ComboBox绑定到SelectedValue无效

[英]ComboBox binding to SelectedValue does not work

I needed to bind a ComboBox to enum values and followed several ideas from so. 我需要将ComboBox绑定到枚举值,并从中得到一些启发。 I ended up with the simplest solution I could find and which should fit all my needs, except it is not working completely, but it should... 最后我找到了最简单的解决方案,该解决方案可以满足我的所有需求,但它不能完全正常工作,但应该...

Heres what I'am doing: I need the ComboBox within a DataGrid cell, so I defined a DataGridTemplateColumn for that 这是我在做什么:我需要在DataGrid单元中使用ComboBox,因此我为此定义了一个DataGridTemplateColumn

<DataGridTemplateColumn MinWidth="150" Header="Data-Type">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox SelectedValue="{Binding SelectedDataType,Mode=TwoWay}" ItemsSource="{Binding DataTypeValues}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

In my ViewModel I populate the enum values 在我的ViewModel中,我会填充枚举值

public IEnumerable<MyType> DataTypeValues
{
    get
    {
        return Enum.GetValues(typeof(MyType)).Cast<MyType>().ToList<MyType>();
    }
}

And have a property for the selected value 并具有所选值的属性

MyType _selectedType;
public MyType SelectedDataType
{
    get { return _selectedType; }
    set
    {
        _selectedType = value;
        OnPropertyChanged();
    }
}

The ComboBox is filled with my enum values as I expected, but when I select another value, the SelectedDataType's setter is not called, meaning I have no information which Item is currently selected. ComboBox充满了我期望的枚举值,但是当我选择另一个值时,不会调用SelectedDataType的setter,这意味着我不知道当前选择了哪个Item。 I also tried to use a SelectedItem binding instead of SelectedValue but that does not work either. 我也尝试使用SelectedItem绑定而不是SelectedValue,但这也不起作用。

What I'am missing here? 我在这里想念的是什么?

edit: typo 编辑:错别字

EDIT2: --------UPDATE-------- 编辑2:--------更新--------

Now I created a sample WPF Application to reproduce my problem. 现在,我创建了一个示例WPF应用程序来重现我的问题。 Only used the relevant code parts in there, and theres the same problem. 仅在其中使用了相关的代码部分,并且存在相同的问题。 Heres the full source code of that example: 这是该示例的完整源代码:

Xaml file: XAML文件:

<Window x:Class="WpfApplication2.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:WpfApplication2"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid ItemsSource="{Binding Parameters}" AutoGenerateColumns="False" SelectedItem="{Binding SelectedParameter, Mode=TwoWay}">
        <DataGrid.Columns>
            <DataGridTemplateColumn MinWidth="150" Header="Data-Type">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding DataTypeValues}" SelectedItem="{Binding SelectedType, Mode=TwoWay}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

And the .cs file: 和.cs文件:

namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        var vm = new Viewmodel();
        DataContext = vm;
    }
}

class Viewmodel : ViewModelBase
{
    public Viewmodel()
    {
        Parameters = new ObservableCollection<Parameter>();
        Parameters.Add(new Parameter());
    }

    public ObservableCollection<Parameter> Parameters
    {
        get; private set;
    }

    public Parameter SelectedParameter { get; set; }
}

class Parameter : ViewModelBase
{
    MyType _selectedType;
    public MyType SelectedType
    {
        get { return _selectedType; }
        set
        {
            _selectedType = value;
            OnPropertyChanged();
        }
    }

    public IEnumerable<MyType> DataTypeValues
    {
        get { return Enum.GetValues(typeof(MyType)).Cast<MyType>(); }
    }
}

public enum MyType
{
    INT,
    DOUBLE,
    REAL,
    STRING
}

public class ViewModelBase : INotifyPropertyChanged
{
    protected virtual void OnPropertyChanged(bool validateFields = true, [CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
}

**EDIT : ** **编辑:**

Yes I got the issue now. 是的,我现在遇到了问题。 Your code is not working since are binding SelectedValue 您的代码无法正常工作,因为已绑定SelectedValue

Instead bind SelectedItem property and check. 而是绑定SelectedItem属性并检查。 It should work. 它应该工作。

<DataGridTemplateColumn MinWidth="150" Header="Data-Type">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ComboBox SelectedItem="{Binding SelectedDataType,Mode=TwoWay}" ItemsSource="{Binding DataTypeValues}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

I think you are binding the selected item inside the window viewmodel,make binding inside the datagrid . 我认为您正在绑定窗口viewmodel内的所选项目,使绑定在datagrid内。 below code worked for me. 下面的代码为我工作。

XAML: XAML:

 <DataGrid Name="datagrid" ItemsSource="{Binding List,Mode=TwoWay}"   >
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Status" Width="100">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox Height="22" 
                                     ItemsSource="{Binding DataContext.DataTypeValues,RelativeSource={RelativeSource AncestorType=Window,
                                                                                        AncestorLevel=1}}"
                                      SelectedItem="{Binding SelectedDataType,UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>               

                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

ViewModel: ViewModel:

 private List<ListItems> list;

        public List<ListItems> List
        {
            get { return list; }
            set
            {
                list = value;
                this.NotifyPropertyChanged("List");
            }
        }

        public IEnumerable<MyType> DataTypeValues
        {
            get
            {
                return Enum.GetValues(typeof(MyType)).Cast<MyType>().ToList<MyType>();
            }
        }

        public ViewModel()
        {
            List = new List<ListItems>();
            List.Add(new ListItems());
            List.Add(new ListItems());

        }

Grid Items: 网格项:

public class ListItems 
    {

        MyType _selectedType;
        public MyType SelectedDataType
        {
            get { return _selectedType; }
            set
            {
                _selectedType = value;
                this.NotifyPropertyChanged("SelectedDataType");
            }
        }
    }

You should use element name while binding to selectedvalue property or selectedItem like 绑定到selectedvalue属性或selectedItem时,应使用元素名称

 <DataTemplate>
                        <ComboBox Height="22" 
                                 ItemsSource="{Binding DataContext.DataTypeValues,RelativeSource={RelativeSource AncestorType=Window,
                                                                                    AncestorLevel=1}}"
                                  SelectedItem="{Binding SelectedDataType,ElementName="datagrid",UpdateSourceTrigger=PropertyChanged}"/>
                    </DataTemplate>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM