You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WPF中DataGridComboBoxColumn默认值未显示问题求助

问题:WPF DataGridComboBoxColumn默认值仅在编辑模式显示,非编辑状态不加载

项目背景

原有连接SQL Server的MS Access 2003 ADP VBA项目,迁移至C# WPF,计划通过DataGrid直接将数据保存到SQL Server。

实现细节

  • DataGrid的ItemsSource绑定INVO_DATA_RASID_KHARID(ObservableCollection类型)
  • 包含ANBAR_COLUMN(DataGridComboBoxColumn),其ItemsSource从SQL Server获取
  • 默认值通过后台FillALLComboboxes方法存入静态变量Baseknow.anbardef,模型类INVO_LST_RASID_KHARID_CSHARP的构造函数为ANBAR属性赋值该默认值

当前问题

ANBAR_COLUMN列的默认值仅在用户双击进入单元格编辑模式时才显示,DataGrid加载完成后默认值不显示,需要实现DataGrid加载完成时直接显示默认值,无需进入编辑模式。


提供的代码

XAML代码

<DataGrid   x:Name="INVO_LST_RASID_SUB"
            EnableColumnVirtualization="True"
            EnableRowVirtualization="True"
            VirtualizingPanel.IsVirtualizing="True"
            VirtualizingPanel.VirtualizationMode="Recycling"
            ScrollViewer.CanContentScroll="False"
        
            KeyboardNavigation.TabNavigation="Contained"
            ItemsSource="{Binding INVO_DATA_RASID_KHARID}"
            Grid.Row="5"
            Margin="5,10"
            AutoGenerateColumns="False"  FlowDirection="RightToLeft"  SelectionUnit="FullRow"   BorderThickness="1" >

    <DataGrid.Columns>

        <DataGridComboBoxColumn x:Name="ANBAR_COLUMN" MinWidth="80" Width="auto" Header=" انبار " 
                                SelectedValueBinding="{Binding ANBAR,UpdateSourceTrigger=PropertyChanged}"
                                DisplayMemberPath="NAMES" SelectedValuePath="CODE">
            <DataGridComboBoxColumn.EditingElementStyle>
                <Style TargetType="{x:Type ComboBox}">
                    <Setter Property="IsEditable" Value="True"/>
                </Style>
            </DataGridComboBoxColumn.EditingElementStyle>

        </DataGridComboBoxColumn>

    </DataGrid.Columns>
</DataGrid>

窗口后台C#代码

//MainWindow:
public partial class HEAD_LST_RASID : Window
{
    public ObservableCollection<INVO_LST_RASID_KHARID_CSHARP> INVO_DATA_RASID_KHARID { get; set; } = new ObservableCollection<INVO_LST_RASID_KHARID_CSHARP>();

    public HEAD_LST_RASID()
    {
        InitializeComponent();
        this.DataContext = this;
    }
    public void FillALLComboboxes()
    {
        string RowSource_ANBAR = "SELECT    CODE, NAMES FROM  dbo.TCOD_ANBAR";
        //Search for the default value if it exists
        var rst = dbms.Database.SqlQuery<int?>("SELECT     ANBCO FROM dbo.OPANBACCESS WHERE     (USERCO = " + Baseknow.USERCOD + " ) ORDER BY dbo.OPANBACCESS.RDF").ToList();
        if (rst.Count > 0)
        {
            Baseknow.anbardef = (int)rst.FirstOrDefault();
        }
        var ARST = dbms.Database.SqlQuery<Custom_TCODANBAR>(RowSource_ANBAR).ToList();
        ANBAR_COLUMN.ItemsSource = ARST;
    }
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        FillALLComboboxes();
        
          var QRE_LST = dbms.Database.SqlQuery<INVO_LST_RASID_KHARID_CSHARP>($@"SELECT * FROM INVOICES").ToList();
          INVO_DATA_RASID_KHARID?.Clear();
          
            foreach (var item in QRE_LST)
                INVO_DATA_RASID_KHARID.Add(item);
    }
}

模型类代码

//Model:
public class CTABLES
{
    public class INVO_LST_RASID_KHARID_CSHARP : INotifyPropertyChanged, ICloneable
    {
        public object Clone()
        {
            return this.MemberwiseClone();
        }
    
        public INVO_LST_RASID_KHARID_CSHARP()
        {
            ANBAR = Baseknow.anbardef;
        }

        private int? _anbar;
        public int? ANBAR
        {
            get
            {
                return _anbar;
            }
            set
            {
                if (_anbar == value)
                    return;
                _anbar = value;
                OnPropertyChanged("ANBAR");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

解决方案

问题根源在于DataGridComboBoxColumn的非编辑状态(默认显示模板)不会自动根据SelectedValue匹配并显示对应的DisplayMember文本,需要自定义单元格模板来实现该逻辑。

方案1:替换为DataGridTemplateColumn,自定义显示与编辑模板

  1. 修改XAML中的ANBAR_COLUMN为DataGridTemplateColumn,分别定义非编辑状态的显示模板和编辑状态的下拉框模板:
<DataGridTemplateColumn x:Name="ANBAR_COLUMN" MinWidth="80" Width="auto" Header=" انبار ">
    <!-- 非编辑状态显示模板 -->
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ANBAR, Converter={StaticResource AnbarCodeToNameConverter}}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <!-- 编辑状态模板 -->
    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding DataContext.AnbarList, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                      SelectedValue="{Binding ANBAR, UpdateSourceTrigger=PropertyChanged}"
                      DisplayMemberPath="NAMES"
                      SelectedValuePath="CODE"
                      IsEditable="True"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
  1. 添加转换器,用于将ANBAR的CODE值转换为对应的名称文本:
public class AnbarCodeToNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is int code && Baseknow.AnbarList != null)
        {
            var targetItem = Baseknow.AnbarList.FirstOrDefault(x => x.CODE == code);
            return targetItem?.NAMES ?? string.Empty;
        }
        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
  1. 修改后台代码,将ANBAR列表存入可访问的位置(静态变量或窗口属性):
// 在窗口类中添加属性
public List<Custom_TCODANBAR> AnbarList { get; set; }

public void FillALLComboboxes()
{
    string RowSource_ANBAR = "SELECT    CODE, NAMES FROM  dbo.TCOD_ANBAR";
    var rst = dbms.Database.SqlQuery<int?>("SELECT     ANBCO FROM dbo.OPANBACCESS WHERE     (USERCO = " + Baseknow.USERCOD + " ) ORDER BY dbo.OPANBACCESS.RDF").ToList();
    if (rst.Count > 0)
    {
        Baseknow.anbardef = (int)rst.FirstOrDefault();
    }
    // 保存列表到属性和静态变量
    AnbarList = dbms.Database.SqlQuery<Custom_TCODANBAR>(RowSource_ANBAR).ToList();
    Baseknow.AnbarList = AnbarList;
}
  1. 在窗口资源中声明转换器:
<Window.Resources>
    <local:AnbarCodeToNameConverter x:Key="AnbarCodeToNameConverter"/>
</Window.Resources>

额外注意事项

  • 确保从数据库查询的INVO_LST_RASID_KHARID_CSHARP对象中,若数据库的ANBAR字段为null,构造函数会正确赋值Baseknow.anbardef
  • 确认Baseknow.anbardef对应的CODE值存在于AnbarList中,否则转换器会返回空文本

内容的提问来源于stack exchange,提问作者مجتبی حکیمیان

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 07:57:02