【问题标题】:Binding Fields to Database and display them in XamDataGrid将字段绑定到数据库并在 XamDataGrid 中显示它们
【发布时间】:2020-10-03 07:24:58
【问题描述】:

早安

在将所有 XamComboBoxEditors 的字段绑定到 XamDataGrid 时,我遇到了一个非常大的问题

在我的数据库中,我有 2 个表:

帐户

public int AccountId { get; set; }
public string Code { get; set; }
public string Code2 { get; set; }
public string Name { get; set; }
public int Parent { get; set; }

和 Acc_Link

public int Acc_LinkId { get; set; }
public string Acc_LinkTitle { get; set; }

我需要在我的 XamDataGrid 3 组合框列中显示:

包含 Acc_Link 表中所有 Acc_LinkTitles 的帐户标题组合框

包含帐户表中所有代码的代码组合框

包含帐户表中所有名称的名称组合框

为了方便我的工作,我创建了一个名为 Acc_LinkObsrvable 的类,其中包含上述字段

但无论我如何尝试,运行代码时 XamDataGrid 中都没有显示任何内容。我尝试在主要的 FieldInitialized 事件中添加代码,以便在代码运行时加载,但又没有出现

我将发布我的代码,请帮助我。

Acc_LinkObsrvable 类:

public string Acc_LinkTitle { get; set; }
public string Code { get; set; }
public string Name { get; set; }

XAML:

<igDP:XamDataGrid DataSource= "{Binding Path=Acc_LinkObservable}" Name="Account_Info_XamDataGrid" FieldLayoutInitialized ="Account_Info_XamDataGrid_FieldLayoutInitialized"  BindToSampleData="False" FieldLayoutInitialized = "Account_Info_XamDataGrid_FieldLayoutInitialized">
<igWPF:XamDataGrid.FieldLayoutSettings>
<igWPF:FieldLayoutSettings AutoGenerateFields="False" />
</igWPF:XamDataGrid.FieldLayoutSettings>
</igDP:XamDataGrid>

在主窗口中:

private void Account_Info_XamDataGrid_FieldLayoutInitialized(object sender, FieldLayoutInitializedEventArgs e)
{
 ComboBoxItemsProvider title_provider = new ComboBoxItemsProvider();
ComboBoxItemsProvider code_provider = new ComboBoxItemsProvider();
ComboBoxItemsProvider name_provider = new ComboBoxItemsProvider();

List<Acc_LinkDTO> Acc_lists = new List<Acc_LinkDTO>();
List<AccountDTO> accounts = new List<AccountDTO>();
FieldLayout fieldLayout = new FieldLayout();

Acc_lists = _Acc_LinkUIAdapter.getAllAcc_Links();
accounts = _AccountUIAdapter.getALlGroup();

//Returns a list of all Account titles
foreach (var x in Acc_lists)
{
    int i = 0;
    title_provider.Items.Add(new ComboBoxDataItem(i, x.Acc_LinkTitle));
    i++;
}
//Returns a list of all codes and names
foreach (var x in accounts)
{
    int i = 0;
    code_provider.Items.Add(new ComboBoxDataItem(i, x.Code));
    name_provider.Items.Add(new ComboBoxDataItem(i, x.Name));
    i++;
}

//First column
Style style1 = new Style(typeof(XamComboEditor));
style1.Setters.Add(new Setter(XamComboEditor.ItemsProviderProperty, title_provider));
var fld1 = new Field()
{
    Name="Acc_LinkTitle",
    Label = "Account Title",
    AlternateBinding = new Binding("Acc_LinkDTO.Acc_LinkTitle"),
    EditorStyle = style1,
    EditorType = typeof(XamComboEditor)
};

e.FieldLayout.Fields.Add(fld1); 

//Second column
Style style2 = new Style(typeof(XamComboEditor));
style2.Setters.Add(new Setter(XamComboEditor.ItemsProviderProperty, code_provider));
var fld2 = new Field()
{
    Name="Code",
    Label = "Code",
    AlternateBinding = new Binding("AccountDTO.Code"),
    EditorStyle = style2,
    EditorType = typeof(XamComboEditor)
};

e.FieldLayout.Fields.Add(fld2); 

//Third column
Style style3 = new Style(typeof(XamComboEditor));
style1.Setters.Add(new Setter(XamComboEditor.ItemsProviderProperty, name_provider));
var fld3 = new Field()
{
    Name="Name",
    Label = "Name",
    AlternateBinding = new Binding("AccountDTO.Name"),
    EditorStyle = style3,
    EditorType = typeof(XamComboEditor)
};

e.FieldLayout.Fields.Add(fld3); 
}

【问题讨论】:

  • Acc_LinkObsrvable 类是如何定义的?
  • 公共类 Acc_LinkObservable { 公共字符串 Acc_LinkTitle { 获取;放; } 公共字符串代码 { 获取;放; } 公共字符串名称 { 获取;放; } }

标签: c# visual-studio binding infragistics xamdatagrid


【解决方案1】:

这个例子展示了不同的方法。 XAML 中定义的所有字段。并且使用 ComboBoxField 代替 XamComboEditor。

MainWindow.xaml

<Window x:Class="XamDataGridDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"           
        xmlns:igWPF="http://infragistics.com/DataPresenter"        
        xmlns:igDP="http://infragistics.com/DataPresenter"        
        xmlns:viewModel="clr-namespace:XamDataGridDemo.ViewModel"
        Title="XamDataGrid Demo" Height="350" Width="525" >
    
    <Window.Resources>
        <ResourceDictionary>
            <viewModel:CategoriesList x:Key="Categories" />
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <igWPF:XamDataGrid x:Name="xamDataGrid1" DataSource="{Binding Path=Products}" Margin="10" >
            
            <igDP:XamDataGrid.FieldLayoutSettings>
                <igDP:FieldLayoutSettings SelectionTypeRecord="None" SelectionTypeField="None" SelectionTypeCell="None" 
                                          AutoGenerateFields="False" HeaderPrefixAreaDisplayMode="None" RecordSelectorLocation="None" >
                </igDP:FieldLayoutSettings>
            </igDP:XamDataGrid.FieldLayoutSettings>
           
            <igDP:XamDataGrid.FieldLayouts>
                <igDP:FieldLayout>
                    <igDP:FieldLayout.Fields>
                        <igDP:Field Label="Name" BindingType="UseAlternateBinding" AlternateBinding="{Binding Path=Name}" HorizontalContentAlignment="Right">
                            <igDP:Field.Settings>
                                <igDP:FieldSettings Width="Auto" AllowEdit="True" />
                            </igDP:Field.Settings>
                        </igDP:Field>
                        <igDP:ComboBoxField Name="Category" Label="Category"
                                            ItemsSource="{Binding Source={StaticResource Categories}}"
                                            DisplayMemberPath="Name" />

                        <igDP:Field Label="Stock" BindingType="UseAlternateBinding" AlternateBinding="{Binding Path=Stock}" HorizontalContentAlignment="Right">
                            <igDP:Field.Settings>
                                <igDP:FieldSettings Width="Auto" AllowEdit="True" />
                            </igDP:Field.Settings>
                        </igDP:Field>
                    </igDP:FieldLayout.Fields>
                </igDP:FieldLayout>
            </igDP:XamDataGrid.FieldLayouts>
        </igWPF:XamDataGrid>
    </Grid>    
</Window>

MainWindow.xaml.cs

using System.Windows;
using System.Collections.ObjectModel;

namespace XamDataGridDemo
{
    public partial class MainWindow : Window
    {
        ObservableCollection<Product> Products = new ObservableCollection<Product>()
        {
            new Product("Porsche 911", "Car", 123),
            new Product("Lenox", "Bicycle", 45),
            new Product("Horizon", "Boat", 67)
        };

        public MainWindow()
        {
            InitializeComponent();
            xamDataGrid1.DataSource = Products;
        }
    }
}

CategoriesList.cs

using System.Collections.ObjectModel;
using Infragistics.Samples.Shared.Models;

namespace XamDataGridDemo.ViewModel
{
    public class CategoriesList : ObservableCollection<CategoryItem>
    {
        public CategoriesList()
        {
            this.Add(new CategoryItem() { Name = "Car" });
            this.Add(new CategoryItem() { Name = "Bicycle" });
            this.Add(new CategoryItem() { Name = "Boat" });
        }
    }

    public class CategoryItem : ObservableModel
    {
        private string _name;
        public string Name
        {
            get
            {
                return this._name;
            }
            set
            {
                if (this._name != value)
                {
                    this._name = value;
                    this.OnPropertyChanged("Name");
                }
            }
        }
    }
}

Product.cs

using System;
using System.ComponentModel;

namespace XamDataGridDemo
{
    public class Product : INotifyPropertyChanged
    {     
        public Product(string name, string category, int stock)
        {
            _name = name;
            _category = category;
            _stock = stock;
        }

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    NotifyPropertyChanged("Name");
                }
            }
        }

        public string Category
        {
            get { return _category; }
            set
            {
                if (_category != value)
                {
                    _category = value;
                    NotifyPropertyChanged("Category");
                }
            }
        }

        public int Stock
        {
            get { return _stock; }
            set
            {
                if (_stock != value)
                {
                    _stock = value;
                    NotifyPropertyChanged("Stock");
                }
            }
        }

        public string _name;
        public string _category;
        public int _stock;

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
        }
    }
}

以下类是从 Infragistics SDK 复制而来的。

ObservableModel.cs

using System.ComponentModel;
using System.Runtime.Serialization;

namespace Infragistics.Samples.Shared.Models
{
    [DataContract]
    public abstract class ObservableModel : INotifyPropertyChanged 
    {
        protected ObservableModel()
        {
            IsPropertyNotifyActive = true;
        }

        #region INotifyPropertyChanged  

        public bool IsPropertyNotifyActive { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        
        protected bool HasPropertyChangedHandler()
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            return handler != null;
        }
        protected void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null && IsPropertyNotifyActive)
                handler(sender, e);
        }
        protected void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            OnPropertyChanged(this, e);
        }
        protected void OnPropertyChanged(object sender, string propertyName)
        {
            OnPropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }
        protected virtual void OnPropertyChanged(string propertyName)
        {
            OnPropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        protected delegate void PropertyChangedDelegate(object sender, string propertyName);

        #endregion
    }
}

如果运行此代码,应用程序窗口将如下所示:

【讨论】:

  • 我完全按照上面的代码,但是当我运行代码时,类别列表总是空的。为什么?
  • @Nour Mawla - 1) 但是xamDataGrid1 包含三个记录? 2)MainWindow 构造函数中的xamDataGrid1.DataSource = Products; 行之后添加以下代码:var categories = ((Infragistics.Windows.DataPresenter.ComboBoxField)xamDataGrid1.FieldLayouts[0].Fields[1]).ItemsSource;。在此行之后放置断点,运行应用程序并检查categories。它包含数据吗? 3) 你的 Infragistics 版本是什么?
【解决方案2】:

Acc_LinkObservable 类应实现 INotifyPropertyChanged 接口。例如:

  public class Acc_LinkObservable : INotifyPropertyChanged
    {     
        public Acc_LinkObservable(string title, string code, string name)
        {
            _acc_LinkTitle = title;
            _code = code;
            _name = name;
        }

        public string Acc_LinkTitle
        {
            get { return _acc_LinkTitle; }
            set
            {
                if (_acc_LinkTitle != value)
                {
                    _acc_LinkTitle = value;
                    NotifyPropertyChanged("Acc_LinkTitle");
                }
            }
        }

        public string Code
        {
            get { return _code; }
            set
            {
                if (_code != value)
                {
                    _code = value;
                    NotifyPropertyChanged("Code");
                }
            }
        }

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    NotifyPropertyChanged("Name");
                }
            }
        }

        public string _acc_LinkTitle;
        public string _code;
        public string _name;

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
        }
    }

之后,XamDataGrid 的数据源可能定义如下: ObservableCollection&lt;Acc_LinkObservable&gt; AccountInfo

相应地在 XAML 中:&lt;igDP:XamDataGrid DataSource= "{Binding Path=AccountInfo}"

现在需要填写AccountInfo

从数据绑定路径中删除 AccountDTO

 AlternateBinding = new Binding("Name"),

检查style3 定义中可能存在的错误打印(样式1 而不是样式3):

Style style3 = new Style(typeof(XamComboEditor));
style1.Setters.Add(new Setter(XamComboEditor.ItemsProviderProperty, name_provider)); 

【讨论】:

  • 如何将我创建的字段(例如 fld1)添加到 Acc_LinkObservable?我创建的字段“Acc_LinkTitle”是一个组合框,而在类中它是字符串类型。我可以使用什么来将组合框插入到 xamdatagrid 而不是字段?
  • @Nour Mawla - 您不需要将字段(例如 fld1)添加到 Acc_LinkObservable。您要添加到FieldLayout 的所有字段(fld1、fld2、fld3)。 Acc_LinkObservable 描述了您的数据模型。
  • 首先让我感谢您给我的时间。请知道我是初学者,所以我不明白的概念。所以我创建了 3 个字段并将它们放在一个字段布局中,我怎样才能将此字段布局添加到 observable 集合中
  • ObservableCollection AccountInfo = new ObservableCollection(fieldLayout);这不起作用
  • Field fld1 = new Field(); fld1.Name = "账户名称";样式 style1 = new Style(typeof(XamComboEditor)); style1.Setters.Add(new Setter(XamComboEditor.ItemsProviderProperty, title_provider)); fld1.Settings.EditorStyle = style1; fld1.Settings.EditorType = typeof(XamComboEditor); fld1.BindingType = BindingType.UseAlternateBinding; fld1.AlternateBinding = new Binding("AccountInfo.Acc_LinkTitle"); fieldLayout.Fields.Add(fld1);
猜你喜欢
  • 1970-01-01
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多