0

Я опытный пользователь Winforms, и теперь я играю с WPF, но я немного борюсь. У меня есть datagrid с 2 столбцами. Первый столбец - это DataGridTextColumn, привязанный к свойству «Имя» моего объекта. Второй столбец привязан к свойству «Власть» моего объекта.Заполнение ComboBox DataGrid со значениями из другого столбца

Когда пользователь редактирует столбец Power, я бы хотел отобразить поле со списком, в котором указано все Имя первого столбца, в дополнение к «None» в качестве первого элемента. Как я могу это сделать?

Кроме того, если пользователь обновляет любое имя первого столбца, я хотел бы, чтобы изменения отражались в столбце Power. Является ли это возможным?

В коде позади:

public partial class MainWindow : Window 
{ 
    ObservableCollection<MyObject> objects = new ObservableCollection<MyObject>(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     dgObjects.ItemsSource = objects; 
    } 
} 

public class MyObject 
{ 
    public String Name { get; set; } 
    public String Power { get; set; } 
} 

В Xaml:

<DataGrid Name="dgObjects" AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Name" Binding="{Binding Name}"/> 
     <DataGridComboBoxColumn Header="Power" Binding="????"/> 
    </DataGrid.Columns> 
</DataGrid> 

Благодаря

+0

Вы могли бы установить и поддерживать свою коллекцию где-то еще, как правило, на том же уровне, что и то, что содержит коллекцию элементов, чтобы связать DataGrid с, а затем привязать 'ComboBox.ItemsSource' к этой коллекции, изменяя' Источник "привязки. В наиболее распространенном сценарии привязка «RelativeSource» используется для поиска родительского «DataGrid» и привязки к «DataGrid.DataContext.SomeCollection». Например, 'ItemsSource =" {Binding DataContext.PowerValues, RelativeSource = {RelativeSource AncestorType = {x: Тип DataGrid}}} "' – Rachel

ответ

0

Вы можете сделать это с помощью связывания на DataContext. Хотя сначала вам нужно правильно настроить Window DataContext. ItemsSource не следует выполнять с помощью кода (это WPF, используйте привязку!).

Установите структуру класса, как:

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

    public class ViewModel 
    { 
     public ObservableCollection<MyObject> Objects { get; } = new ObservableCollection<MyObject>(); 

     public ViewModel() 
     { 
      Objects.Add(new MyObject 
      { 
       Name = "Name" 
      }); 
      Objects.Add(new MyObject 
      { 
       Name = "Name2" 
      }); 
      Objects.Add(new MyObject 
      { 
       Name = "Name3" 
      }); 
     } 
    } 

    public class MyObject 
    { 
     public String Name { get; set; } 
     public String Power { get; set; } 
    } 

Теперь обновите XAML. Вам необходимо будет использовать CellTemplate и стандарт Combobox. Затем ComboBox привязывается к коллекции Objects, отображает имя, но устанавливает значение в Power.

<Window x:Class="WpfApplication8.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" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525" 
     x:Name="MyWindow"> 
    <Grid> 
     <DataGrid Name="dgObjects" AutoGenerateColumns="False" 
        ItemsSource="{Binding Objects}"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="Name" Binding="{Binding Name}"/> 
       <DataGridTemplateColumn> 
        <DataGridTemplateColumn.CellTemplate> 
         <DataTemplate> 
          <ComboBox ItemsSource="{Binding ElementName=MyWindow, Path=DataContext.Objects}" 
             DisplayMemberPath="Name" 
             SelectedItem="{Binding Power}" /> 
         </DataTemplate> 
        </DataGridTemplateColumn.CellTemplate> 
       </DataGridTemplateColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 
+0

Да, я бы рекомендовал что-то подобное, хотя я бы использовал привязку RelativeSource вместо имени 'ElementName', в зависимости от иерархии пользовательского интерфейса – Rachel

+0

@Rachel есть проблемы с производительностью/преимуществами с использованием RelativeSource? –

+0

Возможно, немного быстрее использовать ElementName вместо того, чтобы пересекать визуальное дерево, но я не думаю, что этого достаточно. Я уверен, что кто-то провел некоторые тесты где-то в Интернете, если мы будем искать :) – Rachel

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