从dxe:ComboBoxEdit中获取选定的值

时间:2017-01-09 14:58:31

标签: c# xaml devexpress

我正在使用DevExpress ComboboxEdit对象从用户那里获得多个选择。我的问题是,我不确定选择完成后会回来什么类型的对象。

我已阅读this one,并提出了以下代码,但我不确定我错过了什么。 (我也不确切知道DependencyProperty是什么,但是想避免太多的对象)

<Window x:Class = "Demo.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:Demo"
             xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
             xmlns:dxl="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
             xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
   mc:Ignorable = "d"
   Title = "MainWindow" Height = "350" Width = "525">

    <StackPanel>

        <dxe:ComboBoxEdit ItemsSource="{Binding Path=MyList}"
                          IsTextEditable="False"
                          EditValue="{Binding Path=MySelectedList, Mode=TwoWay}"
                          Name="abc">
            <dxe:ComboBoxEdit.StyleSettings>
                <dxe:CheckedComboBoxStyleSettings/>
            </dxe:ComboBoxEdit.StyleSettings>
        </dxe:ComboBoxEdit>

        <Button Click="showSelected" Content="Show selected items" />

    </StackPanel>

</Window>

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Windows;
using System.Text;

namespace Demo
{

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private System.Collections.Generic.IList<string> _myList;
        private System.Collections.Generic.IList<string> _mySelectedList; // This has probably the wrong type.

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string propertyName)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }


        public IList<string> MyList
        {
            get
            {
                return _myList;
            }

            set
            {
                _myList = value;
                this.RaisePropertyChanged("MyList");
            }
        }

        public IList<string> MySelectedList
        {
            get
            {
                return _mySelectedList;
            }

            set
            {
                _mySelectedList = value;
                this.RaisePropertyChanged("MySelectedList");
            }
        }

        private void showSelected(object sender, RoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            foreach(string s in this.MySelectedList)
            {
                sb.Append(s);
            }
            System.Windows.MessageBox.Show(sb.ToString());
            // This MessageBox show show whatever is checked.
        }

        public MainWindow()
        {
            MySelectedList = new System.Collections.Generic.List<string>();

            MyList = new System.Collections.Generic.List<string>();
            MyList.Add("a");
            MyList.Add("b");
            MyList.Add("c");
            MyList.Add("d");

            DataContext = this;
        }
    }
}

当我运行它并点击组合框时,会出现一个红色X,并显示The type System.Collection.Generic.List´1[System.Object] could not be converted。 MessageBox总是空的。

2 个答案:

答案 0 :(得分:1)

您的MainWindow未实施INotifyPropertyChanged,但这可能不是唯一的问题。在你真正尝试修补WPF之前,我会在Dependency PropertiesData Binding上阅读。如果你不理解这些概念,一切都会变得困难和困惑。

修改

他们似乎正在使用DependencyProperty(正如您所提到的)。但无论如何,这就是你实现一个

的方法
public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register("SelectedItems", typeof(IList), typeof(MainWindow), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemsChanged)));

private static void OnSelectedItemsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    MainWindow mainWindow = o as MainWindow;
    if (mainWindow != null)
        mainWindow.OnSelectedItemsChanged((IList)e.OldValue, (IList)e.NewValue);
}

protected virtual void OnSelectedItemsChanged(IList oldValue, IList newValue)
{
    // Add your property changed side-effects. Descendants can override as well.
}

public IList SelectedItems
{
    // IMPORTANT: To maintain parity between setting a property in XAML and procedural code, do not touch the getter and setter inside this dependency property!
    get
    {
        return (IList)GetValue(SelectedItemsProperty);
    }
    set
    {
        SetValue(SelectedItemsProperty, value);
    }
}

请注意,它必须是IList类型,您需要转换为string

类型

另外,删除绑定中不需要的Mode=TwoWay

<dxe:ComboBoxEdit ItemsSource="{Binding MyList}" EditValue="{Binding SelectedItems}" >
    <dxe:ComboBoxEdit.StyleSettings>
        <dxe:CheckedComboBoxStyleSettings/>
    </dxe:ComboBoxEdit.StyleSettings>
</dxe:ComboBoxEdit>

您也不需要INotifyPropertyChanged这是我的错误。我以为你在做传统的装订。

答案 1 :(得分:0)

EditValue属性包含对象列表,因此VM中的代码应如下所示:

private List<object> _mySelectedList;

public List<object> MySelectedList
{
    get
    {
        return _mySelectedList;
    }

    set
    {
        _mySelectedList = value;
        this.RaisePropertyChanged("MySelectedList");
    }
}

或者您可以编写EditValue转换器,例如,您会找到here