2016-06-16 2 views
1

Я должен предисловие к этому, сказав, что я относительно новичок в работе с WPF и привязками. Я пытаюсь связать ComboBoxItem с ComboBox внутри столбца DataGridTemplate.Bind ComboBoxItem to ComboBox в DataGrid

Насколько я могу судить, привязка действительно работает, потому что ComboBox внутри DataGrid содержит объекты, которые я добавил в код. Проблема, которую я испытываю, заключается в том, что SelectedItem не отображается при назначении внутри конструктора объекта.

Я создал демо-приложение, чтобы воспроизвести проблему.

XAML

<Window x:Class="ComboBoxBindingTests.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:ComboBoxBindingTests" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="500"> 
<Grid> 
    <DataGrid x:Name="dg" ItemsSource="{Binding myCollection}" DataContext="{Binding RelativeSource={RelativeSource AncestorType=Window}}" AutoGenerateColumns="False"> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn Width="200" Header="StringColumn"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <ComboBox ItemsSource="{Binding PossibleStrings}" SelectedItem="{Binding SomeString, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Height="22" /> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
      <DataGridTemplateColumn Width="200" Header="ComboBoxItemColumn"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <ComboBox ItemsSource="{Binding PossibleComboBoxItems}" SelectedItem="{Binding SomeComboBoxItem, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Height="22" /> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 
</Grid> 
</Window> 

Code-Behind

namespace ComboBoxBindingTests 
{ 
public partial class MainWindow : Window 
{ 
    public static ObservableCollection<MyClass> myCollection { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 

     myCollection = new ObservableCollection<MyClass>(); 

     MyClass t = new MyClass("arb1"); 
     myCollection.Add(t); 
    } 
} 



public class MyClass 
{ 
    private ObservableCollection<ComboBoxItem> _possibleComboBoxItems; 
    public ObservableCollection<ComboBoxItem> PossibleComboBoxItems 
    { 
     get { return _possibleComboBoxItems; } 
     set 
     { 
      _possibleComboBoxItems = value; 
      OnPropertyChanged("PossibleComboBoxItems"); 
     } 
    } 
    private ObservableCollection<string> _possibleStrings; 
    public ObservableCollection<string> PossibleStrings 
    { 
     get { return _possibleStrings; } 
     set 
     { 
      _possibleStrings = value; 
      OnPropertyChanged("PossibleStrings"); 
     } 
    } 
    private ComboBoxItem _someComboBoxItem; 
    public ComboBoxItem SomeComboBoxItem 
    { 
     get { return _someComboBoxItem; } 
     set 
     { 
      if (value != null) 
      { 
       ComboBoxItem cbxi = (ComboBoxItem)value; 
       _someComboBoxItem = cbxi; 
       OnPropertyChanged("SomeComboBoxItem"); 
      } 
     } 
    } 
    private string _someString; 
    public string SomeString 
    { 
     get { return _someString; } 
     set 
     { 
      if (value.Contains("System.Windows.Controls.ComboBoxItem: ")) 
       _someString = value.Replace("System.Windows.Controls.ComboBoxItem: ", ""); 
      else 
       _someString = value; 

      OnPropertyChanged("SomeString"); 
     } 
    } 

    public MyClass(string chosenString) 
    { 
     PossibleComboBoxItems = new ObservableCollection<ComboBoxItem>(); 
     PossibleComboBoxItems.Add(new ComboBoxItem() { Content = "arb1", Height = 20, IsEnabled = true }); 
     PossibleComboBoxItems.Add(new ComboBoxItem() { Content = "arb2", Height = 20, IsEnabled = true }); 

     PossibleStrings = new ObservableCollection<string>(); 
     PossibleStrings.Add("arb1"); 
     PossibleStrings.Add("arb2"); 

     SomeString = chosenString; 

     if (chosenString != "") 
     { 
      ComboBoxItem cbxi = new ComboBoxItem(); 
      cbxi.Content = chosenString; 
      cbxi.Height = 20; 
      cbxi.IsEnabled = true; 
      SomeComboBoxItem = cbxi;     
     } 

    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler == null) return; 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
    }   
} 
} 

Поэтому я хочу использовать ComboBoxItem вместо просто строка, что мне нужно, чтобы отобразить объекты в ComboBox, который пользователь не может выбрать. В моем реальном программном обеспечении есть условие, которое устанавливает свойство IsEnabled-false на некоторые объекты.

Я ожидал, что оба столбца в DataGrid отображают «arb1» как SelectedItem, но работает только столбец, связанный с строкой. MainWindow showing that only one column displays the SelectedItem

Я пытался найти решение в течение довольно долгого времени и был бы очень признателен, если бы кто-то мог мне помочь.

ответ

0

После консультации с коллегой я наконец нашел решение.

Линии

ComboBoxItem cbxi = new ComboBoxItem(); 
cbxi.Content = chosenString; 
cbxi.Height = 20; 
cbxi.IsEnabled = true; 
SomeComboBoxItem = cbxi; 

Нужно заменить

SomeComboBoxItem = PossibleComboBoxItems.SingleOrDefault(x => chosenString == x.Content.ToString());