将ComboBoxItem绑定到DataGrid中的ComboBox

时间:2016-06-16 09:16:12

标签: c# wpf data-binding combobox

我应该这样说,我对使用WPF和绑定相对较新。我正在尝试将ComboBoxItem绑定到DataGridTemplate列中的ComboBox。

据我所知,绑定实际上是有效的,因为DataGrid中的ComboBox确实包含我在代码中添加的对象。我遇到的问题是在对象的构造函数内部分配时没有显示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>

代码隐藏

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而不仅仅是String的原因是我需要在ComboBox中显示用户无法选择的对象。在我的实际软件中,有一个条件是在某些对象上将IsEnabled-property设置为false。

我希望DataGrid中的两列都显示&#34; arb1&#34;作为SelectedItem但只有绑定到字符串的列才起作用。 MainWindow showing that only one column displays the SelectedItem

我一直试图找到解决方案已经有一段时间了,如果有人可以帮助我,我会非常感激。

1 个答案:

答案 0 :(得分:0)

在咨询同事后,我终于找到了解决方案。

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

需要替换为

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