2017-01-09 68 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

嘗試在MainWindow上執行System.ComponentModel.INotifyPropertyChanged – Carson

+0

@Carson Done,也引發了setter中的事件,沒有可見的效果。我應該以某種方式註冊處理程序,或者是爲我註冊視圖元素的WPF嗎? –

+0

你不需要註冊任何處理程序。請更新您的代碼,我會嘗試更新我的答案。 – Carson

回答

0

EditValue屬性包含對象的列表,讓你在虛擬機的代碼應該是這樣的:

private List<object> _mySelectedList; 

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

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

或者你可以寫EditValue轉換器,例如,你會發現here

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這是我的錯誤。我以爲你在做傳統的綁定。

+0

爲什麼DependencyProperty很奇怪?你有更好的主意嗎? –

+0

不,我想它本身並不是「奇怪」,但我覺得找到更傳統的管理綁定方法會更直觀。例如,如果他們有一個「SelectedItems」屬性,你可以綁定到返回的「IEnumerable」之類的東西。通常不需要創建一個新的'DependencyProperty'來綁定屬性IMO,如果你想維護剛性的MVVM,它肯定沒有什麼幫助。但是,你總是可以綁定到你的'DependencyProperty',所以我想有一種解決方法。我可能只是過分自以爲是。 – Carson

+0

我的抱怨更多地考慮DevExpress有時處理綁定的方式,但這僅僅是我的看法,並不意味着太多。 – Carson