以编程方式更改 DataGridRow 中的控件

发布于 2024-10-27 13:31:14 字数 426 浏览 4 评论 0原文

我有一个 WPF DataGrid 包含一个产品列表,最后一列中有一个图像按钮,用于将产品项添加到 Orders_Products 集合中。那行得通。

现在,如果产品项已在 Orders_Products 集合中,我想将“添加”图像按钮更改为“删除”图像按钮。

我尝试使用 LoadingRow 事件,但似乎无法访问 Image 对象,因为在 LoadingRow 事件中尚未准备好...

我尝试了 Image 对象的 Load 事件,但如果行不可见,则不会触发它在表单中(当我必须滚动数据网格才能看到该行时)。当我对列进行排序并且该行在表单中直接可见时,它会触发。我快要疯了...:(

我想我没有做任何不寻常的事情,但我是 WPF 的新手,可能我错过了一些东西。

有人能给我一个提示吗? 提前致谢, Joe

P.S.:我正在使用实体框架。

I have a WPF DataGrid contains a list of Products with an image button in the last column to add the Product item into the Orders_Products collection. That works.

Now I'd like to change the "add" image button with a "delete" image button if the Product item is already in the Orders_Products collection.

I tried to use the LoadingRow event but it seems there's no way to access the Image object because is not ready yet in the LoadingRow event...

I tried the Load event of the Image object, but it's not fired if the row is not visible in the form (when I must scroll the datagrid to see that row). It fires when I sort a column and the row is directly visible in the form. I'm going crazy... :(

I think I'm not doing something unusual but I'm new to WPF and probably I miss something.

Can someone give me an hint?
Thanks in advance,
Joe

P.S.: I'm using Entity Framework.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

披肩女神 2024-11-03 13:31:14

执行此操作的正确方法是将 DataGrid 绑定到要显示的对象集合(您可能已经这样做了)。

然后,手动定义 DataGridTemplateColumn 并将其 CellTemplate 设置为适当的 DataTemplate(这通常被定义为 DataGrid 中的资源) 或元素逻辑树中更高的位置)。

您可以查看如何完成上述操作的示例 此处

DataTemplate 内,使用我对这个问题的回答中描述的技术来改变显示的内容通过匹配数据绑定 Product 中适当属性的值来在模板中实现。

所有这些都可以完全在 XAML 中完成,这是在 WPF 中执行操作的首选方式。

更新(工作示例)

Product

public class Product
{
    public string Name { get; set; }

    public bool Exists { get; set; }
}

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.Products = new List<Product>
            {
                new Product { Name = "Existing product", Exists = true },
                new Product { Name = "This one does not exist", Exists = false },
            };

        InitializeComponent();
        this.DataContext = this;
    }

    public IEnumerable<Product> Products { get; set; }
}

MainWindow.xaml

<Window x:Class="SandboxWPF.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>
        <Grid.Resources>
            <DataTemplate x:Key="ButtonColumnTemplate" >
                <ContentControl x:Name="MyContentControl" Content="{Binding}" />
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Exists}" Value="True">
                        <Setter TargetName="MyContentControl" Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <TextBlock Text="Your Remove product button goes here" />
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Exists}" Value="False">
                        <Setter TargetName="MyContentControl" Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <TextBlock Text="Your Add product button goes here" />
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </Grid.Resources>
        <DataGrid ItemsSource="{Binding Products}" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Product Name" Binding="{Binding Name}" />
                <DataGridTemplateColumn Header="Add/Remove" CellTemplate="{StaticResource ButtonColumnTemplate}" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

The proper way of doing this is by binding the DataGrid to the collection of objects you want to display (you are probably doing this already).

Then, manually define a DataGridTemplateColumn and set its CellTemplate to an appropriate DataTemplate (this would usually be defined as a resource in your DataGrid or somewhere higher in the logical tree of elements).

You can see an example of how the above is done here.

Inside the DataTemplate, use the technique described in my answer to this question to vary what is displayed in the template by matching the value of an appropriate property in the databound Product.

All of this can be done entirely in XAML, as is the preferred way of doing things in WPF.

Update (working example)

The Product:

public class Product
{
    public string Name { get; set; }

    public bool Exists { get; set; }
}

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.Products = new List<Product>
            {
                new Product { Name = "Existing product", Exists = true },
                new Product { Name = "This one does not exist", Exists = false },
            };

        InitializeComponent();
        this.DataContext = this;
    }

    public IEnumerable<Product> Products { get; set; }
}

MainWindow.xaml:

<Window x:Class="SandboxWPF.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>
        <Grid.Resources>
            <DataTemplate x:Key="ButtonColumnTemplate" >
                <ContentControl x:Name="MyContentControl" Content="{Binding}" />
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Exists}" Value="True">
                        <Setter TargetName="MyContentControl" Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <TextBlock Text="Your Remove product button goes here" />
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding Exists}" Value="False">
                        <Setter TargetName="MyContentControl" Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <TextBlock Text="Your Add product button goes here" />
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </Grid.Resources>
        <DataGrid ItemsSource="{Binding Products}" AutoGenerateColumns="False" CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Product Name" Binding="{Binding Name}" />
                <DataGridTemplateColumn Header="Add/Remove" CellTemplate="{StaticResource ButtonColumnTemplate}" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文