gpt4 book ai didi

c# - 绑定(bind)到 VM 上同一集合的多个 ItemsControl 无法正确呈现

转载 作者:行者123 更新时间:2023-12-03 10:59:33 26 4
gpt4 key购买 nike

我遇到了一个我认为可能是 WPF 错误的问题。我有一个 WPF View ,其中包含两个 ItemsControl 元素,它们的 ItemsSource 属性都绑定(bind)到 ViewModel 上的同一个 ObservableCollection 属性。我看到的行为是只有在 XAML 中最后声明的 ItemsControl 才能正确呈现其内容。

我的 View 包括以下内容:

<Window x:Class="ItemsControlBindingTest.Views.ItemsControlBindingTestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ItemsControlBindingTestView" Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.ColumnSpan="2" TextWrapping="Wrap">
Note that of the two ItemsControls in this view, only the last declared in XAML renders its contents properly.
</TextBlock>
<ItemsControl Grid.Column="0" Grid.Row="1" ItemsSource="{Binding ButtonList}"/>
<ItemsControl Grid.Column="1" Grid.Row="1" ItemsSource="{Binding ButtonList}"/>
</Grid>
</Window>

你可以看到我只是有一个带有文本 block 和两个 ItemsControl 的网格——每个都绑定(bind)到 ViewModel 上的相同属性。

View 的代码隐藏非常简单:
使用 System.Windows;
使用 ItemsControlBindingTest.ViewModels;
namespace ItemsControlBindingTest.Views
{
/// <summary>
/// Interaction logic for ItemsControlBindingTestView.xaml
/// </summary>
public partial class ItemsControlBindingTestView : Window
{
public ItemsControlBindingTestView()
{
InitializeComponent();
DataContext = new ItemsControlBindingTestViewModel();
}
}
}

您可以看到我只是将 View 的 DataContext 属性设置为 ItemsControlBindingTestViewModel 的新实例。

ItemsControlBindingTestViewModel 的代码:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Controls;

namespace ItemsControlBindingTest.ViewModels
{
public class ItemsControlBindingTestViewModel : MVVM.ViewModelBase
{
private ObservableCollection<Button> buttonList;
public ObservableCollection<Button> ButtonList
{
get { return buttonList; }
set
{
buttonList = value;
NotifyPropertyChanged(() => ButtonList);
}
}

public ItemsControlBindingTestViewModel()
{
List<Button> tempList = new List<Button>();
tempList.Add(new Button { Content = "Button 1" });
tempList.Add(new Button { Content = "Button 2" });
tempList.Add(new Button { Content = "Button 3" });
ButtonList = new ObservableCollection<Button>(tempList);
}
}
}

我们在这里所做的只是将三个按钮添加到 ButtonList 属性。

现在,当我显示此 View 时,我只看到在 XAML 中最后声明的 ItemsControl 中呈现的按钮:

ItemsControl on right is last-declared in XAML

如果我在我的两个 ItemsControls 上切换分配的列值:
<ItemsControl Grid.Column="1" Grid.Row="1" ItemsSource="{Binding ButtonList}"/>
<ItemsControl Grid.Column="0" Grid.Row="1" ItemsSource="{Binding ButtonList}"/>

然后第 0 列(左侧)中的 ItemsControl 将呈现内容,而右侧的 ItemsControl 将保持空白:

ItemsControl on left is last-declared in XAML

查看 Snoop 中的元素会产生一些有趣的信息:

ItemsControls 的 ItemsSource 属性都正确反射(reflect)了与 ButtonList 的绑定(bind)。

Snoop shows first-declared ItemsControl has valid ItemsSource property

其实我可以钻研这个ItemsSource,看到ButtonList中的三个按钮:
Snoop shows me the three buttons in ButtonList

最后声明的 ItemsControl 还显示了一个有效的 ItemsSource 属性:
Last-declared ItemsControl also has valid ItemsSource

我也可以深入研究这个 ItemsSource 并查看 ButtonList 中的三个按钮:
Last-declared ItemsControl ItemsSource has three buttons

Snoop 还显示最后声明的 ItemsControl 的 StackPanel 有子项:
Last-declared ItemsControl's StackPanel has children

虽然第一个声明的 ItemsControl 的 StackPanel 没有子级:
First-declared ItemsControl's StackPanel has no children

我在这里遗漏了什么,还是这是 WPF 中的错误?

最佳答案

如果 ButtonSystem.Windows.Controls.Button ,则行为正常。 Button (与任何其他视觉效果一样),只能有一个父级。当最后一个项目控件呈现一个项目(按钮)时,该项目从前一个父项分离并附加到下一个。

事实上,这是一个非常糟糕的主意——在 View 模型中使用视觉效果。
此外, View 模型的概念在这种情况下失去了意义。如果要在 View 中生成按钮,请为项目控制设置适当的项目模板,并在 View 模型的 ObservableCollection 中保留数据项(不是视觉效果!) .

关于c# - 绑定(bind)到 VM 上同一集合的多个 ItemsControl 无法正确呈现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21054778/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com