【问题标题】:Dynamical / expanding entries for DatagridDatagrid 的动态/扩展条目
【发布时间】:2017-12-04 13:27:34
【问题描述】:

我正在尝试创建一个数据网格,它的条目具有来自 json 的属性。问题是很多属性应该是根据json中的信息动态生成的。

我尝试的第一件事是用自己的 getter 和 setter 列出所有可能的属性。但这是一个很长的列表,感觉应该有一个自动化的解决方案来解决这个问题。这包含在 Datagrid 条目视图模型的末尾。所以我可以在以下情况下绑定到 Number:

Number = obj.NUMBER;

之后我研究了动态类型和expandoObjects。我了解到,显然不可能将 WPF 绑定到 expandoObject 的扩展属性。所以我无法绑定到 expando.Number

expando.Number = obj.NUMBER

我还尝试遵循 this 示例,其中创建了帮助类以帮助绑定,但我似乎无法让它工作。当我运行我的解决方案时,我收到一条错误消息,指出属性“Numberz”不存在。所以我无法绑定到 Numberz:

AddProperty("Numberz", typeof(string));
SetPropertyValue("Numberz", obj.NUMBER);

目前我没有想法,所以如果这里有人可以提供帮助,我将非常感激。也许是一些最后的笔记。我不是一个非常有经验的程序员,我正在尝试通过 MVVM 模式工作。

数据网格入口视图模型

公共类 DatagridEntryViewModel : ICustomTypeProvider, INotifyPropertyChanged { #region 字段

    /// <summary>
    /// Custom Type provider implementation - delegated through static methods.
    /// </summary>
    private readonly CustomTypeHelper<DatagridEntryViewModel> _helper = new CustomTypeHelper<DatagridEntryViewModel>();

    #endregion

    #region Constructor

    public DatagridEntryViewModel(ExitCoil model) 
    {
        _helper.PropertyChanged += (s, e) => PropertyChanged(this, e);

        dynamic Json = JObject.Parse(model.JsonCoilData);
        //CreationDatePost = Json.CREATION_DATE_S_POST;
        ////Number = Json.NUMBER;
        //CreationDatePost = Json.CREATION_DATE_S_POST;
        ////LeverageOrder = Json.LEVERAGE_ORDER;
        //Client = Json.CLIENT;
        //Skinned = Json.SKINNED;

        dynamic expando = new ExpandoObject();
        dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(Json.ToString());
        //AddProperty("Numberz", typeof(string));
        //SetPropertyValue("Numberz", obj.NUMBER);
        //expando.AddItem("Number");
        //expando[0] = obj.NUMBER;
        //Number = expando.Number;


        Model = model;

        //var settings = new JsonSerializerSettings();
        //settings.Converters.Add(new Models.DynamicJsonConverter());
        //var serializer = JsonSerializer.Create(settings);
        //JsonReader reader = new JsonTextReader(new StringReader(JsonString));

        //var Data = serializer.Deserialize<DynamicObject>(reader);
    }

    #endregion

    #region Model & proxy

    private ExitCoil _model;
    public ExitCoil Model
    {
        set { _model = value; }
    }

    #endregion

    #region Public Methods

    // Methods to support dynamic properties.
    public static void AddProperty(string name)
    {
        CustomTypeHelper<DatagridEntryViewModel>.AddProperty(name);
    }

    public static void AddProperty(string name, Type propertyType)
    {
        CustomTypeHelper<DatagridEntryViewModel>.AddProperty(name, propertyType);
    }

    public static void AddProperty(string name, Type propertyType, List<Attribute> attributes)
    {
        CustomTypeHelper<DatagridEntryViewModel>.AddProperty(name, propertyType, attributes);
    }

    public void SetPropertyValue(string propertyName, object value)
    {
        _helper.SetPropertyValue(propertyName, value);
    }

    public object GetPropertyValue(string propertyName)
    {
        return _helper.GetPropertyValue(propertyName);
    }

    public PropertyInfo[] GetProperties()
    {
        return _helper.GetProperties();
    }

    Type ICustomTypeProvider.GetCustomType()
    {
        return _helper.GetCustomType();
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    private void RaisePropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion

    #region Properties

    //public string Number { get; private set; }

    //public string CreationDatePost { get; private set; }

    //public string LeverageOrder { get; private set; }

    public string Client { get; private set; }

    //public int OrderZnTop { get; private set; }

    //public int OrderZnBottom { get; private set; }

    //public string OrderAspect { get; private set; }

    //public string OderSideTrimming { get; private set; }

    //public string OrderPassivation { get; private set; }

    //public string OrderOilType { get; private set; }

    //public string OrderOilQuantity { get; private set; }


    #endregion

}

数据网格视图模型

public class DatagridViewModel : MainViewModelBase
    {
        #region Singleton

        public static DatagridViewModel Instance = new DatagridViewModel();

        #endregion

        #region Fields

        private ObservableCollection<DatagridEntryViewModel> _coilEntries = new ObservableCollection<DatagridEntryViewModel>();
        private readonly IViewManager _viewManager;
        private readonly IDockManager _dockManager;

        #endregion

        #region Properties

        public ObservableCollection<DatagridEntryViewModel> CoilEntries
        {
            get { return _coilEntries; }
            set
            {
                _coilEntries = value;
                RaisePropertyChanged(() => CoilEntries);
            }
        }

        public ProductionExitCoilReport Report { get; set; }

        #endregion

        #region Constructor

        public DatagridViewModel()
        {
            _viewManager = Globals.Container.Resolve<IViewManager>();
            _dockManager = Globals.Container.Resolve<IDockManager>();


            getReport();

            foreach (var Coil in Report.Coils)
            {
                CoilEntries.Add(new DatagridEntryViewModel(Coil));
            }
        }

        #endregion

        #region Methods

        public void getReport()
        {
            var proxy = new Proxy<IReportService>();
            proxy.Open();
            var LijnId = new LijnIdentificatie { Department = "HDG", Firm = "LIE", LineNumber = "05" };
            var Periode = new Period { FromDate = new DateTime(2017 - 11 - 10), FromShift = 1, ToDate = new DateTime(2017 - 11 - 10), ToShift = 1 };
            var request = new ProductionReportRequest() { LijnIdentificatie = LijnId, Period = Periode };
            Report = proxy.Service.GetProductionExitCoilReport(request);


        }

        #endregion
    }

数据网格 XAML

<DataGrid x:Class="Promo.Presentation.Views.CoilGrid"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:mc="http://schemas.openxmlformats.org/marukp-compatibility/2006" 
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
            xmlns:local="clr-namespace:Promo.Presentation.Views"
            xmlns:components="clr-namespace:Promo.Presentation.Components"
            xmlns:Data="clr-namespace:Promo.Presentation.ViewModels"
            AutoGenerateColumns="False"
            GridLinesVisibility="none"
            Background="White"
            Height="Auto"
            Width="Auto"
            MinWidth="500"
            MinHeight="500"
            DataContext="{x:Static Data:DatagridViewModel.Instance}"
            ItemsSource="{Binding CoilEntries}"
            IsReadOnly="True"
            HeadersVisibility="Column"
            Padding="10"
          >

    <DataGrid.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="../Styles/Colors.xaml"/>
                <ResourceDictionary Source="../Styles/Datagrid.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </DataGrid.Resources>

    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Numberz}" Header="Rolnummer" MaxWidth="125"/>
        <DataGridTextColumn Binding="{Binding CreationDatePost}" Header="Post" MaxWidth="200"/>
        <DataGridTextColumn Binding="{Binding LeverageOrder}" Header="Leverage order" MaxWidth="200"/>
        <DataGridTextColumn Binding="{Binding Client}" Header="Client" MaxWidth="400"/>
        <DataGridTextColumn Binding="{Binding OrderZnTop}" Header="Order zinc top" MaxWidth="200"/>
        <DataGridTextColumn Binding="{Binding OrderZnBottom}" Header="Order zinc bottom" MaxWidth="200"/>
        <DataGridTextColumn Binding="{Binding OrderAspect}" Header="Order aspect" MaxWidth="125"/>
        <DataGridCheckBoxColumn Binding="{Binding OrderSideTrimming, Converter={local:StringToBoolConverter}}" Header="Order Side Trimming" MaxWidth="200"/>
        <DataGridTextColumn Binding="{Binding OrderPassivation}" Header="Order Passivation" MaxWidth="200"/>

        <DataGridCheckBoxColumn Binding="{Binding Skinned, Converter={local:StringToBoolConverter}}" Header="Skinned" MaxWidth="200"/>
    </DataGrid.Columns>

</DataGrid> 

Json 的一部分

{"NUMBER":"G571015110","CREATION_DATE_S_POST":"2017-05-11T00:00:00""LEVERAGE_ORDER":"FD72BIGA5W/8","CLIENT":"ARCELORMITTAL BELGIUM SA"}

【问题讨论】:

  • 请仔细阅读整个问题@ASh。我的是我的行具有动态属性,而不是表本身的列。
  • 我确实阅读了整个问题,但缺少一些重要的信息。 json 结构的示例将有所帮助。 DataGrid 为每个条目属性生成一个列,因此动态属性对我来说意味着动态列
  • 那就这样说,而不是说它是重复的。无论如何,我现在已经添加了额外的信息。
  • 如果你有一个包含所有属性的 json,那么 Visual Studio 可以为你生成类!无需自己创建它们。我过去曾处理过类似的情况,之前已经做过:-)。查看基于 json 在 Visual Studio 中生成类。这应该会让你更容易一些。

标签: c# wpf mvvm datagrid


【解决方案1】:

如果您有一个包含所有属性的 json,那么 Visual Studio 可以为您生成类!无需自己创建它们。我过去曾处理过类似的情况,以前已经这样做过。
要粘贴从json 生成的类,请单击要生成代码的 .cs 文件,然后单击 Visual Studio 菜单中的Edit,然后选择Paste Special,然后选择Paste JSON As Classes。
这应该会让你更容易一些。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 2013-01-14
    • 2011-08-31
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    相关资源
    最近更新 更多