【问题标题】:Position a listview control when Datagrid cell text change in wpf当 Datagrid 单元格文本在 wpf 中更改时定位列表视图控件
【发布时间】:2013-09-13 14:58:31
【问题描述】:

我有一个包含 5 列的 Datagrid 控件,分别是 Item Code、Item Name、Qty、Rate、Amount。当我在 Datagrid 的项目名称列的单元格上键入内容时,我想在列表视图控件上填充项目。列表视图必须出现在我输入的单元格下方。我不知道如何在单元格文本更改时获取列表视图的位置。帮助我摆脱这些。

我的窗口是这样的:

 <Grid  Width="900" Height="567" Background="{StaticResource Background}">
      <my:DataGrid Name="dgvSales" BeginningEdit="dgvSales_BeginningEdit" AutoGenerateColumns="False" Margin="13,150,9,117" KeyDown="dgvSales_KeyDown" MouseDown="dgvSales_MouseDown" PreparingCellForEdit="dgvSales_PreparingCellForEdit" MouseRightButtonUp="dgvSales_MouseRightButtonUp">
                    <my:DataGrid.Columns>
                        <my:DataGridTextColumn x:Name="naam" Header="Code" Width="120" Binding="{Binding ProductCode}"></my:DataGridTextColumn>
                        <my:DataGridTextColumn Header="Product Name" Width="200" Binding="{Binding ProductName}"></my:DataGridTextColumn>
                        <my:DataGridComboBoxColumn Header="Unit" Width="100"></my:DataGridComboBoxColumn>
                        <my:DataGridTextColumn Header="Purchase Rate" Width="100" Binding="{Binding PurchaseRate}"></my:DataGridTextColumn>
                        <my:DataGridTextColumn Header="Qty" Width="100" Binding="{Binding Qty}"></my:DataGridTextColumn>
                        <my:DataGridTextColumn Header="Amount" Width="100" Binding="{Binding Amount}"></my:DataGridTextColumn>
                    </my:DataGrid.Columns>
                </my:DataGrid>

<ListView Height="161" ItemsSource="{Binding}" Margin="461,0,51,257" Name="lstvwProductCode" VerticalAlignment="Bottom" Visibility="Collapsed" Width="388">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn DisplayMemberBinding="{Binding Path=Record_Id}" Header="Record ID" Width="0" />
                            <GridViewColumn DisplayMemberBinding="{Binding Path=Product_Code}" Header="Pcode" Width="110" />
                            <GridViewColumn DisplayMemberBinding="{Binding Path=Product_Name}" Header="Product" Width="180" />
                        </GridView>
                    </ListView.View>
                </ListView>
</Grid>

【问题讨论】:

    标签: c# wpf datagrid


    【解决方案1】:

    您可以像这样获得 ListViewItem 的位置:

    FrameworkElement item = (FrameworkElement)DataGrid.ItemContainerGenerator.ContainerFromItem(data);
    Point position = item.TranslatePoint(new Point(0, item.ActualHeight), Window.GetWindow(DataGrid));
    

    现在您可以更改 ListView 的位置:

    ListView.RenderTransform = new TranslateTransform(position.X, position.Y);
    

    编辑: 你也可以使用BeginningEdit-Event的EventArgs:

        private void DataGrid_OnBeginningEdit(object sender, DataGridBeginningEditEventArgs e)
        {
            Point newPosition = new Point();
            if (!(lstvwProductCode.RenderTransform is TransformGroup))
                lstvwProductCode.RenderTransform = new TransformGroup();// set the ListView's RenderTransform to a TransformGroup if it isn't already
    
            DataGrid dg = GetRowsDataGrid(e.Row); //get the Row's corresponding DataGrid with the help of the VisualTreeHelper. You cant use the Column here, because it won't get added to the visual tree.
            if (dg != null)
            {
                double rowX = GetColumnXPosition(e.Column, dg); //get the x position. Here you can't use .TranslatePoint because - again - it doesn't belong to the visual tree, so you have to sum up all columns width' to the column where the changes are made.
                newPosition = e.Row.TranslatePoint(new Point(rowX + 5, e.Row.ActualHeight), this); //translate this point to a point on your main window.
            }
    
            if (newPosition != new Point())
            {
                Point tPoint = lstvwProductCode.TranslatePoint(new Point(0, 0), this);//add this point
                ((TransformGroup) lstvwProductCode.RenderTransform).Children.Add(
                    new TranslateTransform(newPosition.X - tPoint.X, newPosition.Y - tPoint.Y));
            }
        }
    
        private double GetColumnXPosition(DataGridColumn column, DataGrid grid)
        {
            double result = 0.0;
    
            if (grid == null)
                return result;
    
            for (int i = 0; i < grid.Columns.Count; i++)
            {
                DataGridColumn dgc = grid.Columns[i];
                if (dgc.Equals(column))
                    break;
    
                result += dgc.ActualWidth;
            }
            return result;
        }
    
        private DataGrid GetRowsDataGrid(DataGridRow row)
        {
            DependencyObject result = VisualTreeHelper.GetParent(row);
            while (result != null && !(result is DataGrid))
            {
                result = VisualTreeHelper.GetParent(result);
            }
            return result as DataGrid;
        }
    

    【讨论】:

    • 嗨 Florian Gl,我不明白 data 和 lvi 是什么意思,你可以澄清一下。FrameworkElement item = (FrameworkElement)DataGrid.ItemContainerGenerator.ContainerFromItem(data);点位置 = lvi.TranslatePoint(new Point(0, item.ActualHeight), Window.GetWindow(DataGrid));
    • 对不起,lvi 是复制粘贴错误,我改了。 data 是您要获取的 DataGridItem 的 DataContext。例如。如果您的 DataGrid 绑定到对象列表,则数据是此列表的一项。
    • 嗨 Florian Gl,我将我的 Datagrid 项目源绑定到可观察集合
    • 好的,FrameworkElement item = (FrameworkElement)DataGrid.ItemContainerGenerator.ContainerFromItem(YourObservableCollection[0]); 会给你 DataGrid 的第一个项目。
    • 先生,好的,我照你说的做了。现在显示了我的列表视图,但它位于我当前表单(用户控件)的下方,但实际上我想将列表视图放置在我输入 ProductName 的单元格上,感谢您的帮助,先生
    猜你喜欢
    • 1970-01-01
    • 2017-08-07
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    相关资源
    最近更新 更多