Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF中的绑定数据_C#_Wpf_Data Binding_Wpfdatagrid - Fatal编程技术网

C# WPF中的绑定数据

C# WPF中的绑定数据,c#,wpf,data-binding,wpfdatagrid,C#,Wpf,Data Binding,Wpfdatagrid,我正在尝试用c#制作简单的WPF应用程序,我有以下问题: 在我的应用程序中,我使用类“Macierz”来表示和处理BigInteger对象数组。现在我需要使用DataGrid(或者其他更好的方法)以图形方式表示这个数组,我不知道如何将这个DataGrid绑定到我的类。我曾试图通过数据源窗口(VS2013)来实现这一点,但当我将类添加到其中时,我的数组没有显示出来。 下面是我班的一些代码: public class Macierz { public Macierz(ulong A, ulo

我正在尝试用c#制作简单的WPF应用程序,我有以下问题: 在我的应用程序中,我使用类“Macierz”来表示和处理BigInteger对象数组。现在我需要使用DataGrid(或者其他更好的方法)以图形方式表示这个数组,我不知道如何将这个DataGrid绑定到我的类。我曾试图通过数据源窗口(VS2013)来实现这一点,但当我将类添加到其中时,我的数组没有显示出来。 下面是我班的一些代码:

public class Macierz
{
    public Macierz(ulong A, ulong B)
    {
        a = A;
        b = B;
        M = new BigInteger[A, B];
    }


    private ulong a, b;
    public ulong A
    {
        get
        {
            return a;
        }
    }

    public ulong B
    {
        get
        {
            return b;
        }
    }

    private BigInteger[,] M;

    public BigInteger this[ulong A, ulong B]
    {
        get
        {
            return M[A, B];
        }
        set
        {
            M[A, B] = value;
        }
    }
 public DataTable ToDataTable()
    {
        DataTable table = new DataTable();
        DataRow tmp;
        for (ulong i = 0; i < b; i++)
            table.Columns.Add(i.ToString(), typeof(BigInteger));

        for (ulong i = 0; i < a; i++)
        {
            tmp = table.NewRow();
            for (ulong j = 0; j < b; j++)
                tmp[j.ToString()] = M[i, j];

            table.Rows.Add(tmp);
        }
        return table;
    }
我需要用文本框的单元格或类似的东西来表示数组,这样用户就可以轻松地更改特定单元格的值

编辑: 现在,感谢user3148019 answer,我在我的类中添加了此方法:

public class Macierz
{
    public Macierz(ulong A, ulong B)
    {
        a = A;
        b = B;
        M = new BigInteger[A, B];
    }


    private ulong a, b;
    public ulong A
    {
        get
        {
            return a;
        }
    }

    public ulong B
    {
        get
        {
            return b;
        }
    }

    private BigInteger[,] M;

    public BigInteger this[ulong A, ulong B]
    {
        get
        {
            return M[A, B];
        }
        set
        {
            M[A, B] = value;
        }
    }
 public DataTable ToDataTable()
    {
        DataTable table = new DataTable();
        DataRow tmp;
        for (ulong i = 0; i < b; i++)
            table.Columns.Add(i.ToString(), typeof(BigInteger));

        for (ulong i = 0; i < a; i++)
        {
            tmp = table.NewRow();
            for (ulong j = 0; j < b; j++)
                tmp[j.ToString()] = M[i, j];

            table.Rows.Add(tmp);
        }
        return table;
    }
这工作得很好,允许我以简单的方式向用户显示数组,但我现在不知道如何允许用户更改原始数组中的值。我曾试图使用CellEditEnding DataGrid事件,但现在我不知道如何访问、读取和验证用户在特定单元格中的输入,特别是如何获取该单元格的坐标(我可能会以某种方式获取类似于“e.Column.something”或“e.Row.something”的信息,但我不知道如何做到这一点)

  • Macierz
    应派生自
    DependencyObject

  • 不能使用多维数组进行绑定

  • 使用
    ObservableCollection
    而不是简单数组

  • 使用
    dependencProperty
    而不是简单的数据类型

  • DataGrid
    DataContext
    设置为所需的
    Macierz


  • 编辑: 你问的问题非常笼统,为了找到一个好的答案,我建议你试试这个方法,当你掌握了窍门后,再问另一个关于你可能遇到的其他问题的问题。例如,如何将ulong用作ObservableCollection的ListSelector,或者如何将页面添加到ItemsControl,或者如何使用具有动态列数的DataGrid

    在我开始之前,我必须说这个答案只适用于小尺寸的Macierz,其中两个维度都是int,对于A*B>10000,它变得非常慢

    这里的想法是创建一个
    ItemsControl
    ,它是一种基本类型的容器,用于显示一个
    可观察集合

    • ItemsSource
      :集合的源(您绑定到该集合)
    • ItemTemplate
      :每个项目的模板(如何显示集合中的每个项目,我使用了TextBlock(在边框内),因为它的加载速度比TextBox快)
    • ItemContainerStyle
      :每个项目容器的样式。(
      Grid.Row
      Grid.Column
      必须按照此成员中提供的样式设置。)
    • ItemsPanel
      :项目控制面板的模板。(我使用了具有动态行数和列数的
      网格
      ,并使用了
      GridHelper
    现在,您可以为M创建一个一维集合。此集合的泛型类型应配备
    行索引
    列索引
    ,以便每个元素都知道它在
    网格中所属的位置

    这是MainWindow.xaml.cs:

    private void PokazButton_Click(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.Wait;
    
            if (czyCala.IsChecked == true)
                GridTabela = M.ToDataTable(0, M.A, 0, M.B);
            else
                GridTabela = M.ToDataTable(VA, VACount, VB, VBCount);
    
            TabelaDataGrid.DataContext = this;
            TabelaDataGrid.ItemsSource = GridTabela.DefaultView;
    
            this.Cursor = null;
        }
    
    InitializeComponent();
    var mac = new Macierz(100,40);
    
    //fill with test data
    for (int i = 0; i < mac.A; i++)
    {
        for (int j = 0; j < mac.B; j++)
        {
            mac[i, j].Data = string.Format("{0}...{1}", i, j);
        }
    }
    
    //set DataContext
    this.DataContext = mac;
    
    您还需要一个助手类。这是GridHelper的简化版本。您可以在的中找到原始类:

    公共类GridHelper
    {
    #区域行计数属性
    /// 
    ///将指定数量的行添加到行定义中。
    ///默认高度为“自动”
    /// 
    公共静态只读DependencyProperty RowCountProperty=
    DependencyProperty.RegisterAttached(
    “行计数”、typeof(int)、typeof(GridHelper),
    新属性元数据(-1,RowCountChanged));
    //得到
    公共静态int GetRowCount(DependencyObject obj)
    {
    返回(int)对象GetValue(RowCountProperty);
    }
    //设置
    公共静态void SetRowCount(DependencyObject对象,int值)
    {
    对象设置值(RowCountProperty,value);
    }
    //更改事件-添加行
    公共静态无效行数已更改(
    DependencyObject对象,DependencyPropertyChangedEventArgs e)
    {
    如果(!(对象是网格)| |(int)e.NewValue<0)
    回来
    网格网格=(网格)obj;
    grid.RowDefinitions.Clear();
    对于(int i=0;i<(int)e.NewValue;i++)
    grid.RowDefinitions.Add(
    新建行定义(){Height=GridLength.Auto});
    //设置箭头(网格);
    }
    #端区
    #区域列计数属性
    /// 
    ///将指定数量的列添加到ColumnDefinitions。
    ///默认宽度为“自动”
    /// 
    公共静态只读DependencyProperty ColumnCountProperty=
    DependencyProperty.RegisterAttached(
    “ColumnCount”、typeof(int)、typeof(GridHelper),
    新属性元数据(-1,ColumnCountChanged));
    //得到
    公共静态整型GetColumnCount(DependencyObject obj)
    {
    返回(int)对象GetValue(ColumnCountProperty);
    }
    //设置
    公共静态void SetColumnCount(DependencyObject对象,int值)
    {
    对象设置值(ColumnCountProperty,value);
    }
    //更改事件-添加列
    公共静态无效列数已更改(
    DependencyObject对象,DependencyPropertyChangedEventArgs e)
    {
    如果(!(对象是网格)| |(int)e.NewValue<0)
    回来
    网格网格=(网格)obj;
    grid.ColumnDefinitions.Clear();
    对于(int i=0;i<(int)e.NewValue;i++)
    grid.ColumnDefinitions.Add(
    新ColumnDefinition(){Width=GridLength.Auto});
    //柱(网格);
    }
    #端区
    }
    
    如果没有额外的工作,阵列无法绑定到DataGrid。一种快速解决方案是使用DataTable而不是多维数组:

    <Window x:Class="StackExchange.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid AutoGenerateColumns="True" Name="myGrid"/>
    </Grid>
    

    我将类更改为从DependencyObject派生,但我不知道下一步该做什么。我应该用l替换我的数组吗
    public class Macierz : DependencyObject
    {
        public Macierz(int A, int B)
        {
            this.A = A;
            this.B = B;
            for (int i = 0; i < A; i++)
            {
                for (int j = 0; j < B; j++)
                {
                    M.Add(new BigInteger(i, j));
                }
            }
        }
    
        //A Dependency Property
        public int A
        {
            get { return (int)GetValue(AProperty); }
            private set { SetValue(AProperty, value); }
        }
        public static readonly DependencyProperty AProperty =
            DependencyProperty.Register("A", typeof(int), typeof(Macierz), new UIPropertyMetadata(0));
        //B Dependency Property
        public int B
        {
            get { return (int)GetValue(BProperty); }
            private set { SetValue(BProperty, value); }
        }
        public static readonly DependencyProperty BProperty =
            DependencyProperty.Register("B", typeof(int), typeof(Macierz), new UIPropertyMetadata(0));
        //Rows Observable Collection
        public ObservableCollection<BigInteger> M { get { return _m; } }
        private ObservableCollection<BigInteger> _m = new ObservableCollection<BigInteger>();
    
        public BigInteger this[int i, int j]
        {
            get { return M[i * B + j]; }
            set { M[i * B + j] = value; }
        }
    }
    
    //replace this class with your own implementation.
    //derive from DependencyObject and use DependencyProperty to store data
    public class BigInteger : DependencyObject
    {
        public BigInteger(int row, int col)
        {
            RowIndex = row;
            ColumnIndex = col;
        }
        //Data Dependency Property
        public string Data
        {
            get { return (string)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }
        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(string), typeof(BigInteger), new UIPropertyMetadata(""));
        //RowIndex Dependency Property
        public int RowIndex
        {
            get { return (int)GetValue(RowIndexProperty); }
            set { SetValue(RowIndexProperty, value); }
        }
        public static readonly DependencyProperty RowIndexProperty =
            DependencyProperty.Register("RowIndex", typeof(int), typeof(BigInteger), new UIPropertyMetadata(0));
        //ColumnIndex Dependency Property
        public int ColumnIndex
        {
            get { return (int)GetValue(ColumnIndexProperty); }
            set { SetValue(ColumnIndexProperty, value); }
        }
        public static readonly DependencyProperty ColumnIndexProperty =
            DependencyProperty.Register("ColumnIndex", typeof(int), typeof(BigInteger), new UIPropertyMetadata(0));
    }
    
    public class GridHelper
    {
        #region RowCount Property
    
        /// <summary>
        /// Adds the specified number of Rows to RowDefinitions. 
        /// Default Height is Auto
        /// </summary>
        public static readonly DependencyProperty RowCountProperty =
            DependencyProperty.RegisterAttached(
                "RowCount", typeof(int), typeof(GridHelper),
                new PropertyMetadata(-1, RowCountChanged));
    
        // Get
        public static int GetRowCount(DependencyObject obj)
        {
            return (int)obj.GetValue(RowCountProperty);
        }
    
        // Set
        public static void SetRowCount(DependencyObject obj, int value)
        {
            obj.SetValue(RowCountProperty, value);
        }
    
        // Change Event - Adds the Rows
        public static void RowCountChanged(
            DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (!(obj is Grid) || (int)e.NewValue < 0)
                return;
    
            Grid grid = (Grid)obj;
            grid.RowDefinitions.Clear();
    
            for (int i = 0; i < (int)e.NewValue; i++)
                grid.RowDefinitions.Add(
                    new RowDefinition() { Height = GridLength.Auto });
    
            //SetStarRows(grid);
        }
    
        #endregion
    
        #region ColumnCount Property
    
        /// <summary>
        /// Adds the specified number of Columns to ColumnDefinitions. 
        /// Default Width is Auto
        /// </summary>
        public static readonly DependencyProperty ColumnCountProperty =
            DependencyProperty.RegisterAttached(
                "ColumnCount", typeof(int), typeof(GridHelper),
                new PropertyMetadata(-1, ColumnCountChanged));
    
        // Get
        public static int GetColumnCount(DependencyObject obj)
        {
            return (int)obj.GetValue(ColumnCountProperty);
        }
    
        // Set
        public static void SetColumnCount(DependencyObject obj, int value)
        {
            obj.SetValue(ColumnCountProperty, value);
        }
    
        // Change Event - Add the Columns
        public static void ColumnCountChanged(
            DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (!(obj is Grid) || (int)e.NewValue < 0)
                return;
    
            Grid grid = (Grid)obj;
            grid.ColumnDefinitions.Clear();
    
            for (int i = 0; i < (int)e.NewValue; i++)
                grid.ColumnDefinitions.Add(
                    new ColumnDefinition() { Width = GridLength.Auto });
    
            //SetStarColumns(grid);
        }
    
        #endregion
    }
    
    <Window x:Class="StackExchange.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid AutoGenerateColumns="True" Name="myGrid"/>
    </Grid>
    
    public DataTable Macierz;
    
    public MainWindow()
    {
        InitializeComponent();
    
        Macierz = new DataTable("Table");
        Macierz.Columns.Add("Col1", typeof(int));
        Macierz.Columns.Add("Col2", typeof(int));
        Macierz.Columns.Add("Col3", typeof(int));
    
        DataRow row1 = Macierz.NewRow();
        row1["Col1"] = 1;
        row1["Col2"] = 2;
        row1["Col3"] = 3;
        Macierz.Rows.Add(row1);
    
        DataRow row2 = Macierz.NewRow();
        row2["Col1"] = 4;
        row2["Col2"] = 5;
        row2["Col3"] = 6;
        Macierz.Rows.Add(row2);
    
        myGrid.DataContext = this;
        myGrid.ItemsSource = Macierz.DefaultView;
    }