2017-01-09 2 views
0

Я использую объект DevExpress ComboboxEdit для получения множественного выбора от пользователя. Моя проблема заключается в том, что я не уверен, какой тип объекта будет возвращен после выбора.Получить выбранные значения из dxe: 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 всегда пуст.

+0

Попробуйте внедрить System.ComponentModel.INotifyPropertyChanged на MainWindow – Carson

+0

@Carson Done, также поднял событие в сеттерах, без видимого эффекта. Должен ли я как-то регистрировать обработчики или WPF регистрирует элементы представления для меня? –

+0

Вам не нужно регистрировать обработчиков. Обновите свой код, и я попытаюсь обновить свой ответ. – Carson

ответ

0

EditValue свойство содержит список объектов, так что ваш код в VM должен выглядеть следующим образом:

private List<object> _mySelectedList; 

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

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

Или вы можете написать EditValue конвертер, пример вы найдете here.

1

У вас нет INotifyPropertyChanged на вашем MainWindow, но это может быть не единственная проблема. Я читал Dependency Properties и Data Binding, прежде чем вы действительно попытаетесь возиться с WPF. Если вы не понимаете эти концепции, все будет сложно и запутанно.

EDIT

Они используют 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, что было моей ошибкой. Я думал, вы делаете традиционную привязку.

+0

Почему DependencyProperty нечетный? У вас есть идея? –

+0

Нет, я думаю, это не «странно» как таковое, но я чувствую, что поиск более традиционных средств управления привязкой будет более интуитивным. Например, если у них есть свойство «SelectedItems», которое вы могли бы связать с возвращаемым «IEnumerable» или что-то еще. Обычно нет необходимости создавать новый 'DependencyProperty' для привязки к свойству IMO, и это, безусловно, не полезно, если вы хотите поддерживать жесткий MVVM. Но вы всегда можете привязываться к своей «DependencyProperty», так что есть способ обойти это, я полагаю. Я, вероятно, просто слишком самоуверен. – Carson

+0

Моя ручка больше думает вслух о том, как DevExpress иногда обрабатывает привязки, но это просто мое мнение, это мало значит. – Carson

Смежные вопросы