2016-06-17 20 views
0

Ich musste eine ComboBox an Enum-Werte binden und folgten mehrere Ideen aus so. Ich landete mit der einfachsten Lösung, die ich finden konnte und die sollte alle meine Bedürfnisse passen, außer es funktioniert nicht vollständig, aber es sollte ...ComboBox Bindung an SelectedValue funktioniert nicht

Heres, was ich mache: Ich brauche die ComboBox in einem DataGrid Zelle, so definiert ich eine Datagridtemplatecolumn für das

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

In meinem Viewmodel besiedeln ich die enum

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

Werte und eine Eigenschaft haben, für den gewählten Wert

Die ComboBox ist wie erwartet mit meinen Enum-Werten gefüllt, aber wenn ich einen anderen Wert auswähle, wird der Setter des SelectedDataType nicht aufgerufen, was bedeutet, dass ich keine Informationen darüber habe, welches Element gerade ausgewählt ist. Ich habe auch versucht, eine SelectedItem-Bindung anstelle von SelectedValue zu verwenden, aber das funktioniert auch nicht.

Was fehlt mir hier?

edit: Typo

EDIT2: -------- -------- UPDATE

Jetzt habe ich eine Probe WPF-Anwendung, mein Problem zu reproduzieren. Benutzte nur die relevanten Code-Teile darin, und Theres das gleiche Problem. Heres die vollständigen Quellcode dieses Beispiel:

XAML-Datei:

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

Und die CS-Datei:

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; 
} 
} 
+0

Ich habe versucht, mehr Variationen, aber es scheint wie das Problem ist die Verwendung der ComboBox innerhalb des DataGrid. Der obige Viewmodel-Code funktioniert gut, wenn ich die ComboBox an einem anderen Teil meiner Anwendung verwende. Aber wenn ich die CellTemplate der DataGridColumn definiere und die ComboBox dort zusammen mit dem hinterlegten Code verwende, funktioniert die Bindung an den ausgewählten Wert nicht wie beschrieben .... irgendwelche Ideen? Irgendetwas stimmt nicht mit meinem XAML? – Milhouse

+0

Überprüfen Sie jetzt. Ich habe die Antwort aktualisiert. Es funktioniert gut von meiner Seite. – ViVi

Antwort

0

** EDIT: **

Ja, ich habe das Problem jetzt. Ihr Code funktioniert nicht, da sind verbindlich SelectedValue

Stattdessen binden SelectedItem Eigenschaft und überprüfen. Es sollte funktionieren.

+0

Danke für Ihren Vorschlag. Ich habe das jetzt versucht, aber immer noch dasselbe Ergebnis. Ich bekomme die Werte in die ComboBox, aber die Bindung an SelectedItem oder SelectedValue funktioniert nicht mit diesem Ansatz: -/ – Milhouse

+0

Jetzt prüfen. Ich habe die Antwort aktualisiert. Es funktioniert gut von meiner Seite. – ViVi

+0

Haben Sie dies überprüft – ViVi

0

Ich denke, Sie binden das ausgewählte Element innerhalb des Fensters Viewmodel, binden Sie in das DataGrid. unter Code funktionierte für mich.

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> 

Ansichtsmodell:

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

public class ListItems 
    { 

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

Sie sollten Elementname verwenden, während die Bindung wie Eigentum oder selectedItem SelectedValue

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

Nicht verstehen, dass ... wie sollte diese Bindung funktionieren ... Bindung des SelectedItem meines ComboBox an das übergeordnete DataGrid SelectedItem. Für mich ergibt das keinen Sinn ... – Milhouse

+0

Entschuldigung für die späte Antwort, aber das funktioniert für mich, wenn Sie Ihre Komponente mit dem Datenkontext der Elternkomponente binden, dann übernimmt Kind automatisch den Datenkontext der Eltern. –

Verwandte Themen