【问题标题】:WPF change datagrid combobox ItemsSource to value of another datagrid comboxWPF 将 datagrid 组合框 ItemsSource 更改为另一个 datagrid 组合框的值
【发布时间】:2012-11-30 03:30:00
【问题描述】:

我有一个包含 2 个 DataGridComboxClolumn 元素的数据网格,并且想要在第一个元素的值发生更改时更改第二个元素的 ItemsSource。如何设置这样的绑定?

注意:数据网格有自己的项目源,数据是分层的:

数据网格的ItemsSource(列表操作类型Channel):

public class Root
{
    public List<Channel> Ch { get; set; }  // This is the ItemsSource of the datagrid itself
}


public class Channel
{
    public Settings TheSettings { get; set; }
}

我想要完成的事情是使用第二个 ComboBox 的选定值设置 TheSettings。这可以通过设置 ComboBox ItemsSource 轻松完成。虽然我要求第二个组合框的 ItemsSource 是动态的。例如。它必须更改为在 FIRST 组合框中选择的源。如何做到这一点?

【问题讨论】:

    标签: c# wpf datagrid datagridcomboboxcolumn


    【解决方案1】:

    选项 1

    您可以使用两个组合框创建 DataGridTemplateColumn。第一个可以填充来自主 ViewModel 的项目,第二个将绑定到第一个的 SelectedItem 的项目。

    <Window x:Class="WpfApplication1.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:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="525"
        Height="350"
        mc:Ignorable="d">
    <Window.DataContext>
        <local:Root/>
    </Window.DataContext>
    <Grid x:Name="LayoutRoot">
        <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Ch}" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <ComboBox  Width="100" ItemsSource="{Binding DataContext.ComboBox1Items, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" x:Name="ComboBox1"/>
                            <ComboBox Grid.Column="1" Width="100" ItemsSource="{Binding SelectedItem.Items, ElementName=ComboBox1}" SelectedItem="{Binding TheSettings}" IsEditable="True" IsReadOnly="True"/>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    
    </Grid>
    </Window>
    
    public class ComboBox1Item
    {
        public string Label { get; set; }
        public List<string> Items { get; set; }
    
        public override string ToString()
        {
            return this.Label;
        }
    }
    
    public class Root
    {
        public List<Channel> Ch { get; set; }
    
        public List<ComboBox1Item> ComboBox1Items { get; set; }
    
        public Root()
        {
            this.Ch = new List<Channel>(){
                new Channel(){ TheSettings = "Settings1"},
                new Channel(){ TheSettings = "Settings2"},
            };
    
            this.ComboBox1Items = new List<ComboBox1Item>{
                new ComboBox1Item(){ Label = "Item1",
                    Items = new List<string>(){ "Settings1", "Settings2"}
                },
                new ComboBox1Item(){ Label = "Item2",
                    Items = new List<string>(){ "Settings3", "Settings4"}
                }
            };
        }
    }
    

    选项 2

    创建一个对象来包装您的 Channel 对象,并在其中放入逻辑以允许一个组合框驱动另一个组合框的项目:

    public class ChannelWrapper : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged values
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    
    
        private object comboBox1SelectedItem;
        public object ComboBox1SelectedItem
        {
            get { return this.comboBox1SelectedItem; }
            set
            {
                if (this.comboBox1SelectedItem != value)
                {
                    this.comboBox1SelectedItem = value;
                    this.OnPropertyChanged("ComboBox1SelectedItem");
    
                    // Put the logic to change the items available in the second combobox here
                    if (value == "Value1")
                        this.ComboBox2ItemsSource = new List<object>() { "Setting1", "Setting2" };
                    if (value == "Value2")
                        this.ComboBox2ItemsSource = new List<object>() { "Setting3", "Setting4" };
                }
            }
        }
    
        private List<object> comboBox2ItemsSource;
        public List<object> ComboBox2ItemsSource
        {
            get { return this.comboBox2ItemsSource; }
            set
            {
                if (this.comboBox2ItemsSource != value)
                {
                    this.comboBox2ItemsSource = value;
                    this.OnPropertyChanged("ComboBox2ItemsSource");
                }
            }
        }
    
        public Channel Ch { get; set; }
    }
    

    然后,您的 Root 类将公开一组包装器,而不是一组通道。您的 DataGrid 将有 2 个 ComboBoxColumns。第一个的 SelectedItem 将绑定到包装器的属性“ComboBox1SelectedItem”。第二个的 ItemsSource 将绑定到 wrapper 的属性“ComboBox2ItemsSource”,第二列的 SelectedItem 将绑定到 wrapper 的 Channel 实例的设置,路径为“Ch.TheSettting”。

    【讨论】:

      猜你喜欢
      • 2013-01-23
      • 1970-01-01
      • 2013-09-30
      • 1970-01-01
      • 2021-05-01
      • 2023-03-05
      • 1970-01-01
      • 2018-06-24
      • 2011-03-02
      相关资源
      最近更新 更多