代码之家  ›  专栏  ›  技术社区  ›  Hussain

将附加列与数据网格WPF中的任何控件绑定

  •  0
  • Hussain  · 技术社区  · 10 年前

    我有一个要求,即使用WPF C#在数据网格内的列表视图或数据网格中绑定额外的列。

    基本数据网格如下

    <table border="1" width="100%">
        <tr>
        	<td>Item Id</td>
        	<td>Item Name</td>
        	<td>Quantity</td>
        	<td>Price</td>
        </tr>
        <tr>
        	<td>500</td>
        	<td>Sanwich</td>
        	<td>2</td>
        	<td>10</td>
        </tr>
    </table>

    对于以上内容 datagrid 我的 XAML 代码如下。

    <DataGrid Grid.Column="1" Margin="8,60,8,16"AutoGenerateColumns="False" Height="350"
         HorizontalAlignment="Left" Name="gridOrderDetails" VerticalAlignment="Top" Width="450" >
        <DataGrid.Columns>
            <DataGridTextColumn Header="Item ID" Binding="{Binding itemId}" />                                        
    
            <DataGridTextColumn Header="Quantity" Binding="{Binding quantity}" />
            <DataGridTextColumn Header="Item Name" Binding="{Binding comments}" />
            <DataGridTextColumn Header="Item Price" Binding="{Binding ItemPrice}" />
        </DataGrid.Columns>
    </DataGrid>
    

    我的代码隐藏代码如下:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            DBDataContext dbContext = new DBDataContext();
            SP_Get_OrderItemResult orderRow = gridOrder.SelectedItem as SP_Get_OrderItemResult;
    
            gridOrderDetails.ItemsSource = dbContext.SP_Get_ItemList(orderRow.orderid);
        }
        catch (Exception Ex)
        {
            MessageBox.Show(Ex.Message);
            return;
        }
    }
    

    我期望的输出如下

    <table border="1" width="100%">
        <tr>
        	<td>Item Id</td>
        	<td>Item Name</td>
        	<td>Additionals</td>
        	<td>Quantity</td>
        	<td>Price</td>
        </tr>
        <tr>
        	<td>500</td>
        	<td>Sanwich</td>
        	<td>Egg<p class="MsoNormal" style="margin-left:0in">Ketchup</p>
        	<p>
        	<span style="font-size: 11.0pt; line-height: 115%; font-family: Calibri,sans-serif">
        	Salad</span></td>
        	<td>2</td>
        	<td>10</td>
        </tr>
    </table>

    为了实现这一点 数据网格 我写了我的 XAML公司 使用以下代码 DataGridTemplateColumn .

    <DataGrid Grid.Column="1" Margin="8,60,8,16"AutoGenerateColumns="False" Height="350"
        HorizontalAlignment="Left" Name="gridOrderDetails" VerticalAlignment="Top" Width="450" LoadingRow="gridOrderDetails_LoadingRow">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Item ID" Binding="{Binding itemId}" />
            <DataGridTextColumn Header="Item Name" Binding="{Binding ItemName}" />
            <DataGridTemplateColumn Header="Addtionals">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <DataGrid AutoGenerateColumns="False" Name="gridAdditionals" >
                            <DataGridTextColumn Header="Additional" Binding="Additionals"></DataGridTextColumn>
                        </DataGrid>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>         
        <DataGridTextColumn Header="Quantity" Binding="{Binding quantity}" />
            <DataGridTextColumn Header="Comments" Binding="{Binding comments}" />
            <DataGridTextColumn Header="Item Price" Binding="{Binding ItemPrice}" />
        </DataGrid.Columns>
    </DataGrid>
    

    在我尝试的代码背后 LoadingRow 事件,但无法传递相应的 ItemID 来自单元格值。

    private void gridOrderDetails_LoadingRow(object sender, DataGridRowEventArgs e)
    {
        DCAPPDBDataContext dbContext = new DCAPPDBDataContext();
    
        DataGrid grid = FindChild<DataGrid>(gridOrderDetails, "gridAdditionals");
        grid.ItemsSource = dbContext.SP_Get_AdditionalsList(500);
    } 
    

    我想我使用的逻辑是错误的。这可以通过使用 ItemDataBound 在Asp。net C#。 有人能帮我在WPF C#中做这件事吗。

    2 回复  |  直到 10 年前
        1
  •  1
  •   Bahman_Aries    10 年前

    使用时 WPF 遵循 MVVM 图案无论哪种方式,您都应该为您的 Order (包含Id、名称、数量等属性…)。此类还应具有 Aditionals (例如 strings ). 然后使用适当的 DataBindings 您将实现所需的功能。

    这是一个很好的例子,可以给你一个想法:

    订单类别:

    public class Order : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
    
        void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    
        public Order(int id)
        {
            DBDataContext dbContext = new DBDataContext();
            DCAPPDBDataContext dbContext2 = new DCAPPDBDataContext();
    
            var itemsSource = dbContext.SP_Get_ItemList(id);
            var additionals = dbContext2.SP_Get_AdditionalsList(id);
    
            Id = id;
            Name = itemsSource.name;
            Quantity = itemsSource.quantity;
            // other properties ...
    
            Additionals = new ObservableCollection<string>();
            foreach (var item in additionals)
            {
                Additionals.Add(item);
            }
        }
    
        private int _id;
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
                OnPropertyChanged("Id");
            }
        }
    
        // define other properties e.g. Name, Quantity, Price, etc.
        // the same way as Id.
    
        public ObservableCollection<string> Additionals {get;set;}
    }
    

    Xaml:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <DataGrid Grid.Row="0" AutoGenerateColumns="False"
              ItemsSource="{Binding Orders}" 
              SelectedItem="{Binding SelectedOrder}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Item ID" Binding="{Binding Id}" />
            <DataGridTextColumn Header="Item Name" Binding="{Binding Name}" />
            <DataGridTemplateColumn Header="Addtionals">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                            <ItemsControl ItemsSource="{Binding Additionals}">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding}"/>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="Quantity" Binding="{Binding Quantity}" />
            <DataGridTextColumn Header="Item Price" Binding="{Binding Price}" />
        </DataGrid.Columns>
    </DataGrid>
    <Button  Grid.Row="1" Content="New Order" Click="Order_Click"/>
    </Grid>
    

    主窗口.cs:

        public ObservableCollection<Order> Orders { get; set; }
    
        public Order SelectedOrder { get; set; }
    
        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
    
            Orders = new ObservableCollection<Order>();
    
        }
    
        private void Order_Click(object sender, RoutedEventArgs e)
        {
            SP_Get_OrderItemResult orderRow = gridOrder.SelectedItem as SP_Get_OrderItemResult;
            Orders.Add(new Order(orderRow.orderid));
        }
    
        2
  •  1
  •   Hussain    10 年前

    在Bahman_Aries的帖子和一些小东西的帮助下,我发布了准确的解决方案。 这正是我想要的解决方案。

    订单类别:

    public class Order : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
    
        void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    
        public Order(SP_Get_ItemListResult itemResult)
        {
            DBDataContext dbContext = new DBDataContext();                
    
    
             orderItemID = itemResult.orderItemID;
            itemName = itemResult.ItemName;
            quantity = itemResult.quantity;           
            // other properties ...
    
          var additionals = dbContext.SP_Get_AdditionalsList(orderItemID);
    
            Additionals = new ObservableCollection<string>();
            foreach (var item in additionals)
            {
                Additionals.Add(item.Additionals);
            }
        }
    
        private int _id;
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
                OnPropertyChanged("Id");
            }
        }
    
        // define other properties e.g. Name, Quantity, Price, etc.
        // the same way as Id.
    
        public ObservableCollection<string> Additionals {get;set;}
    }
    

    XAML代码中没有更改。

    主窗口.cs:

    public ObservableCollection<Order> Orders { get; set; }
    
    public Order SelectedOrder { get; set; }
    
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    
        Orders = new ObservableCollection<Order>();
    
    }
    
    private void Order_Click(object sender, RoutedEventArgs e)
    {
        SP_Get_OrderItemResult orderRow = gridOrder.SelectedItem as SP_Get_OrderItemResult;
          List<SP_Get_ItemListResult> itemsSource = dbContext.SP_Get_ItemList(orderRow.orderid).ToList();
                for (int i = 0; i < itemsSource.Count(); i++)
                {
                    Orders.Add(new Order(itemsSource[i]));
                }         
    }
    
    推荐文章