当 Items 改变时如何触发 cellTemplateSelector

发布于 2024-12-06 21:21:52 字数 904 浏览 1 评论 0原文

我有 2 个 DataGrid 的 CellTemplate 模板。当我更改项目时,它不会帮助我选择模板,甚至不会调用我的 DisplayModeTemplateSelector!

我想知道是否有办法在项目更改时再次触发此 CellTemplateSelector ?当内容更改时如何刷新 DataGrid 或 ListView 中的 CellTemplate

<DataGridTemplateColumn x:Name="colorRange"
                        Width="*"
                        Header="Color Range">
    <DataGridTemplateColumn.CellTemplateSelector>
        <local:DisplayModeTemplateSelector HeatMapTemplate="{StaticResource heatMapTemplate}" ThreshHoldTemplate="{StaticResource threshHoldTemplate}" />
    </DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>

我发现了这个博客 http://dotdotnet.blogspot.com/2008/11 /refresh-celltemplate-in-listview-when.html

我认为这和我的问题类似,但我真的无法理解他!谁能解释一下吗?

I have 2 templates for DataGrid's CellTemplate. When I change the items, it won't help me select the template for me, my DisplayModeTemplateSelector won't even be called!

What I'm wondering is if there is a way to trigger this CellTemplateSelector again when items changed? How to refresh CellTemplate in DataGrid or ListView When Content Changes

<DataGridTemplateColumn x:Name="colorRange"
                        Width="*"
                        Header="Color Range">
    <DataGridTemplateColumn.CellTemplateSelector>
        <local:DisplayModeTemplateSelector HeatMapTemplate="{StaticResource heatMapTemplate}" ThreshHoldTemplate="{StaticResource threshHoldTemplate}" />
    </DataGridTemplateColumn.CellTemplateSelector>
</DataGridTemplateColumn>

I found this blog
http://dotdotnet.blogspot.com/2008/11/refresh-celltemplate-in-listview-when.html

I think this is similar with my problem, but I really can't understand him! Can anyone explain it?

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

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

发布评论

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

评论(2

夏日落 2024-12-13 21:21:52

博客文章中的解决方案不适用于 DataGrid 控件,因为 DataGridTemplateColumn 类不属于可视化树,即使我尝试将其绑定到静态类,由于属性更改后出现奇怪的异常,我没有成功。

无论如何,有两种可能的方法来解决这个问题。

1)更简单的方法。

使用 ObservableCollection 类。

    var itemIndex = 0;
    var currentItem = vm.Items[itemIndex];
    //Change necessary properties
    //..
    vm.Items.Remove(currentItem);
    vm.Items.Insert(itemIndex, currentItem);      

2)更复杂的方式。

您可以将返回对象本身的属性添加到项目类中。

    public ItemViewModel(/*...*/)
    {
        this.SelfProperty = this;
        //...
    }

    public ItemViewModel SelfProperty { get; private set; }

    public void Update()
    {
        this.SelfProperty = null;
        this.OnPropertyChanged("SelfProperty");
        this.SelfProperty = this;
        this.OnPropertyChanged("SelfProperty");
    }

之后,您可以使用 ContentControl.ContentTemplateSelector 而不是 CellTemplateSelector,如下所示:

            <DataGridTemplateColumn Header="Color Range">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ContentControl Content="{Binding SelfProperty}"  ContentTemplateSelector="{StaticResource mySelector}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

当您更改属性时,以某种方式调用 Update 方法:

  currentItem.SomeDataProperty = "some new value";
  //Or you can add this method call to the OnPropertyChanged 
  //so that it calls authomatically
  currentItem.Update(); 

我首先在 Update 方法中为 SelfProperty 设置空值的原因是,Selector 不会更新模板,直到Content 属性完全改变了。如果我再次设置相同的对象 - 不会发生任何事情,但如果我首先为其设置空值 - 将处理更改。

The solution in the blog post will not work with the DataGrid control because the DataGridTemplateColumn class doesn't belong to the Visual Tree, and even when I tried to bind it to a static class, I didn't suceed because of strange exceptions after property changes.

Anyway there is two possible ways to solve this problem.

1) The easier way.

Using the ObservableCollection class.

    var itemIndex = 0;
    var currentItem = vm.Items[itemIndex];
    //Change necessary properties
    //..
    vm.Items.Remove(currentItem);
    vm.Items.Insert(itemIndex, currentItem);      

2) The more complex way.

You can add to your item class the property which returns the object itself.

    public ItemViewModel(/*...*/)
    {
        this.SelfProperty = this;
        //...
    }

    public ItemViewModel SelfProperty { get; private set; }

    public void Update()
    {
        this.SelfProperty = null;
        this.OnPropertyChanged("SelfProperty");
        this.SelfProperty = this;
        this.OnPropertyChanged("SelfProperty");
    }

After that you can use the ContentControl.ContentTemplateSelector instead of the CellTemplateSelector like this:

            <DataGridTemplateColumn Header="Color Range">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ContentControl Content="{Binding SelfProperty}"  ContentTemplateSelector="{StaticResource mySelector}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

And when you change the property, call the Update method somehow:

  currentItem.SomeDataProperty = "some new value";
  //Or you can add this method call to the OnPropertyChanged 
  //so that it calls authomatically
  currentItem.Update(); 

The reason why I've set a null value to the SelfProperty in the Update method first, is that the Selector will not update a template until the Content property is completely changed. If I set the same object once again - nothing will happen, but if I set a null value to it first - changes will be handled.

猥︴琐丶欲为 2024-12-13 21:21:52

最简单的方法是挂钩组合框的 Selection Changed 事件,并重新分配模板选择器。这会强制刷新。

在 XAML 中(假设 DataGrid/ComboBoxColumn 的其余部分:

<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
    <Setter Property="ItemsSource" 
            Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}},  Path=DataContext.Gates, UpdateSourceTrigger=PropertyChanged}"/>
    <EventSetter Event="SelectionChanged" Handler="GateIDChanged" />
</Style>

那指的是这个DataGridTemplateColumn:

<DataGridTemplateColumn x:Name="GateParamsColumn" Header="Gate Parameters" CellTemplateSelector="{StaticResource GateParamsTemplateSelector}"></DataGridTemplateColumn>

并且在后面的代码中:

private void GateIDChanged(object sender, SelectionChangedEventArgs eventArgs)
{
    var selector = GateParamsColumn.CellTemplateSelector;
    GateParamsColumn.CellTemplateSelector = null;
    GateParamsColumn.CellTemplateSelector = selector;
}

The easy way is to hook the Combo Box's Selection Changed event, and reassign the template selector. This forces a refresh.

In XAML (assume the rest of the DataGrid/ComboBoxColumn:

<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
    <Setter Property="ItemsSource" 
            Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}},  Path=DataContext.Gates, UpdateSourceTrigger=PropertyChanged}"/>
    <EventSetter Event="SelectionChanged" Handler="GateIDChanged" />
</Style>

That refers to this DataGridTemplateColumn:

<DataGridTemplateColumn x:Name="GateParamsColumn" Header="Gate Parameters" CellTemplateSelector="{StaticResource GateParamsTemplateSelector}"></DataGridTemplateColumn>

And in the code behind:

private void GateIDChanged(object sender, SelectionChangedEventArgs eventArgs)
{
    var selector = GateParamsColumn.CellTemplateSelector;
    GateParamsColumn.CellTemplateSelector = null;
    GateParamsColumn.CellTemplateSelector = selector;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文