WPF DataTemplate 和属性中的奇怪行为。

发布于 2024-08-04 11:35:56 字数 2557 浏览 4 评论 0原文

我有一个在 StackPanel 中显示按钮的 DataTemplate。每当用户单击按钮时,该按钮就应该发光。因此,我在模板中编写了必要的 DataTrigger,并在我要绑定的属性中编写了布尔条件。详细信息如下:

<DataTemplate x:Key="ActionItemsTemplate" DataType="ActionItemViewModel">

        <ItemsControl IsTabStop="False" ItemsSource="{Binding}" Margin="6,2">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>                    
                    <StackPanel Orientation="Horizontal" />                        
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

            <ItemsControl.ItemTemplate>
                <DataTemplate>

                    <Button x:Name="ActionButton" Command="{Binding Path=Command }" Content="{Binding Path=DisplayName}" Style="{DynamicResource HeaderButton}"/>
                    <!-- Set special values for Selected Item -->
                    <DataTemplate.Triggers>
                        <DataTrigger Binding="{Binding IsSelected}" Value="True">
                            <Setter TargetName="ActionButton" Property="Style"  Value="{DynamicResource MainWindowSelectedButton}"/>
                            <!--Command="{Binding Path=Command}" Content="{Binding Path=DisplayName}"-->
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DataTemplate>

我已经实现了 INotifyPropertyChanged 接口,并且 Property ActionItems 返回一个 ObservableCollection。

问题:当我更改 ObservableCollection 并调用 INotifyPropertyChanged 事件时,它不会直接反映在 DataTemplate 中,而只会更改属性。但是,如果我将整个对象重新分配给它自己,它就会完美地工作。

例如,

void Test1()
        {
           _commands[0].IsSelected = !_commands[0].IsSelected;               
            _commands[0] = _commands[0];      // Does not work If this line is commented out        
            ActionItems = _commands;
        }

问题可能是什么?

编辑:我发现在这种情况下问题可能出在数据绑定上。

我现在遇到了类似的问题,我已将 Expander 控件的 IsExpanded 属性绑定到 TabPanel 内的 bool 属性。当我切换 bool 属性时,值会在后面更改,但不会反映在显示中。但是,假设我更改选项卡并返回,我会看到更改已经发生。这与这里的问题有关吗?

我再次想知道问题可能是什么(稍微缩小范围:))

编辑2:第二个问题的解决方案:我发现每当以编程方式更新时都需要调用 INotifyPropertyChanged 接口的 OnPropertyChangedEvent于 IsExpanded 属性已更新。至于原始问题,情况似乎并非如此,我仍在试图找出问题所在。 :)

I have a DataTemplate that displays buttons in a StackPanel. Whenever a user clicks a button, the button is supposed to glow. So I have written the necessary DataTrigger in the Template and a Boolean condition in the property that I'm binding too. Here are the details below:

<DataTemplate x:Key="ActionItemsTemplate" DataType="ActionItemViewModel">

        <ItemsControl IsTabStop="False" ItemsSource="{Binding}" Margin="6,2">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>                    
                    <StackPanel Orientation="Horizontal" />                        
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>

            <ItemsControl.ItemTemplate>
                <DataTemplate>

                    <Button x:Name="ActionButton" Command="{Binding Path=Command }" Content="{Binding Path=DisplayName}" Style="{DynamicResource HeaderButton}"/>
                    <!-- Set special values for Selected Item -->
                    <DataTemplate.Triggers>
                        <DataTrigger Binding="{Binding IsSelected}" Value="True">
                            <Setter TargetName="ActionButton" Property="Style"  Value="{DynamicResource MainWindowSelectedButton}"/>
                            <!--Command="{Binding Path=Command}" Content="{Binding Path=DisplayName}"-->
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </DataTemplate>

I have implemented the INotifyPropertyChanged interface and the Property ActionItems returns an ObservableCollection.

The Problem: When I change the ObservableCollection and call the INotifyPropertyChanged event, it is not reflected in the DataTemplate directly, but only altering the property. However if I re-assgn the entire object with itself, it works perfectly.

e.g

void Test1()
        {
           _commands[0].IsSelected = !_commands[0].IsSelected;               
            _commands[0] = _commands[0];      // Does not work If this line is commented out        
            ActionItems = _commands;
        }

What could the problem be?

Edit: I see that the problem could be with the DataBinding in this case.

I have arrived at a similar problem now where I have bound the IsExpanded property of the Expander control to a bool property inside a TabPanel. When I toggle the bool property, the value is changed behind, but not reflected in the display. However suppose I change tabs and come back, I see the change has taken place. Is this related to this problem here?

And again I wonder what the problem could be (narrowed it down a bit :))

Edit 2: Solution for second Problem: I found that the OnPropertyChangedEvent of the INotifyPropertyChanged Interface needs to be called whenever a programmatic update on the
IsExpanded property is updated. As for the Original Problem, this does not seem to be the case, and I'm still trying to figure out what is going wrong. :)

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

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

发布评论

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

评论(2

半岛未凉 2024-08-11 11:35:56

我相信你无法替换该集合,只能更改其内容。

I'm led to believe that you cannot replace the collection, only alter its contents.

苏大泽ㄣ 2024-08-11 11:35:56

我也绑定的属性中的布尔条件

我不完全确定您在这里的意思,但我猜测这是您的“命令”上的 IsSelected 属性,并且您忘记为该属性引发 PropertyChanged 。

a Boolean condition in the property that I'm binding too

I am not completely sure what you mean here, but I take the guess that this is the IsSelected property on your "commands" and that you forgot to raise PropertyChanged for that property.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文