2016-06-17 2 views
0

Мне нужно было привязать ComboBox к значениям перечисления и следовать нескольким идеям. Я закончил с самым простым решением, которое я смог найти, и которое должно соответствовать всем моим потребностям, кроме того, что оно не работает полностью, но оно должно ...Связывание ComboBox с SelectedValue не работает

Вот что я делаю: Мне нужен ComboBox в DataGrid клетка, поэтому я определил DataGridTemplateColumn для этого

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

В моей ViewModel я заселить перечисление значений

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

И имеют свойство для выбранного значения

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

ComboBox заполнен моими значениями перечисления, как я ожидал, но когда я выбираю другое значение, setter SelectedTataType не вызывается, то есть у меня нет информации, которую элемент в данный момент выбран. Я также попытался использовать привязку SelectedItem вместо SelectedValue, но это тоже не работает.

Что мне здесь не хватает?

редактировать: опечатка

EDIT2: -------- ОБНОВЛЕНИЕ --------

Теперь я создал образец приложения WPF, чтобы воспроизвести мою проблему. Используйте только соответствующие части кода там, и проблема та же. Heres полный исходный код этого примера:

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> 

И файл .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; 
} 
} 
+0

Я попробовал больше вариантов, но похоже, что проблема заключается в использовании ComboBox в DataGrid. Вышеупомянутый код viewmodel отлично работает, когда я использую ComboBox в другой части моего приложения. Но когда я определяю CellTemplate в DataGridColumn и использую ComboBox там вместе с опубликованным кодом, привязка к выбранному значению не работает, как описано ... любые идеи? Что-то не так с моим XAML? – Milhouse

+0

Проверьте сейчас. Я обновил ответ. Он отлично работает с моей стороны. – ViVi

ответ

0

** EDIT: **

Да, у меня проблема. Ваш код не работает, поскольку привязываются SelectedValue

Вместо этого свяжите SelectedItem и проверьте его. Он должен работать.

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

Спасибо за ваше предложение. Я попробовал это сейчас, но все тот же результат. Я получаю значения в ComboBox, но привязка к SelectedItem или SelectedValue не работает ни с этим подходом: -/ – Milhouse

+0

. Я обновил ответ. Он отлично работает с моей стороны. – ViVi

+0

Вы проверили это – ViVi

0

Я думаю, что вы привязываете выбранный элемент в окне viewmodel, создаете привязку внутри datagrid. ниже код работал для меня.

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:

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()); 

     } 

сетки элементов:

public class ListItems 
    { 

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

Вы должны использовать имя элемента, а привязка к SelectedValue собственности или SelectedItem как

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

Не понимайте, что ... как эта обязательная работа ... Связывание SelectedItem моего ComboBox с родительским DataGrid SelectedItem. Не имеет смысла для меня ... – Milhouse

+0

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

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