【问题标题】:Bind ComboBoxItem to ComboBox in DataGrid将 ComboBoxItem 绑定到 DataGrid 中的 ComboBox
【发布时间】:2016-06-16 09:16:11
【问题描述】:

我应该先说我对使用 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 属性设置为 false。

我希望 DataGrid 中的两列都将“arb1”显示为 SelectedItem,但只有绑定到字符串的列有效。

一段时间以来,我一直在努力寻找解决方案,如果有人能帮助我,我将不胜感激。

【问题讨论】:

    标签: c# wpf data-binding combobox


    【解决方案1】:

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

    线条

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

    需要替换为

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

    【讨论】:

      猜你喜欢
      • 2014-10-10
      • 1970-01-01
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 2014-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多