2017-02-22 70 views
0

Мне нужен был DataGrid с одним или несколькими DataGridTextColumn, который изменил его свойство Binding.Path, когда выбранный элемент ComboBox в его заголовке изменяется. ItemsSource этого ComboBox должен быть списком свойств в модели.MVVM; DataGridTextColumn с ComboBox в заголовке, который определяет привязку столбца

Однако Path не является DependencyProperty и поэтому не может быть связан.

Я столкнулся с этой проблемой, пока я пытался ответить на вопрос vague question. Фактически, я не был уверен, что это то, что он хочет, и поэтому я думал, что отправлю его как отдельный Q & A.

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

Не удалось найти какой-либо подобный вопрос. This one похоже, похоже, не реализует MVVM.

+1

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

+1

Точно. На основе [этой политики] (http://stackoverflow.com/help/self-answer) – Ron

+0

проблема в том, что вы только что вставили код, не объясняя ничего –

ответ

1

Предполагая, что модель имеет два свойства Name и Desc:

public class Model : INotifyPropertyChanged 
{ 
    string _desc; 
    public string Desc { get { return _desc; } set { _desc = value; RaisePropertyChanged("Desc"); } } 

    string _name; 
    public string Name { get { return _name; } set { _name = value; RaisePropertyChanged("Name"); } } 

    public event PropertyChangedEventHandler PropertyChanged; 
    internal void RaisePropertyChanged(string propname) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname)); 
    } 
} 

Модель вид должен получить список этих свойств (Items) и имеют SelectedItem, который указывает текущее выбранное свойство. Другие вещи, обычные свойства модели представления:

public class ViewModel : INotifyPropertyChanged 
{ 
    public ViewModel() 
    { 
     Models = new ObservableCollection<Model>() { new Model() {Name = "aaaa", Desc = "desc1" }, new Model() { Name = "bbbbb", Desc="desc2" } }; 

     Items = new ObservableCollection<PropertyInfo>(typeof(Model).GetProperties()); 
     SelectedItem = Items[0]; 
    } 
    ObservableCollection<PropertyInfo> _items; 
    public ObservableCollection<PropertyInfo> Items { get { return _items; } set { _items = value; RaisePropertyChanged("Items"); } } 

    PropertyInfo _selectedItem; 
    public PropertyInfo SelectedItem { get { return _selectedItem; } set { 
      _selectedItem = value; RaisePropertyChanged("SelectedItem"); 
     } } 

    ObservableCollection<Model> _models; 
    public ObservableCollection<Model> Models { get { return _models; }set { _models = value; RaisePropertyChanged("Models"); } } 

    public event PropertyChangedEventHandler PropertyChanged; 
    void RaisePropertyChanged(string propname) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname)); 
    } 
} 

мнение нуждается в MultiBinding, чтобы получить выбранные свойства значение:

<DataGrid DataContext="{Binding}" ItemsSource="{Binding Models}" AutoGenerateColumns="False"> 
    <DataGrid.Resources> 
     <local:conv1 x:Key="conv1" /> 
    </DataGrid.Resources> 
    <DataGrid.Columns> 
     <DataGridTextColumn> 
      <DataGridTextColumn.Binding> 
       <MultiBinding Converter="{StaticResource conv1}"> 
        <Binding /> 
        <Binding Path="DataContext.SelectedItem" RelativeSource="{RelativeSource AncestorType=DataGrid, Mode=FindAncestor}" /> 
       </MultiBinding> 
      </DataGridTextColumn.Binding> 
      <DataGridTextColumn.Header> 
       <ComboBox DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType=DataGrid, Mode=FindAncestor}}" 
          ItemsSource="{Binding Items}" SelectedItem ="{Binding SelectedItem, Mode=TwoWay}"/> 
      </DataGridTextColumn.Header> 
     </DataGridTextColumn> 
    </DataGrid.Columns> 
</DataGrid> 

, в котором

public class conv1 : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     Model m = values[0] as Model; 
     PropertyInfo pi = values[1] as PropertyInfo; 
     if (m != null && pi != null) 
     { 
      return pi.GetValue(m); 
     } 
     return Binding.DoNothing; 
    } 
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

и

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     this.InitializeComponent(); 
     DataContext = new ViewModel(); 
    } 
} 

, что приводит к следующим образом:

enter image description here