【问题标题】:Unhandled exception `The parameter is incorrect` in NotifyCollectionChangedEvent handlerNotifyCollectionChangedEvent 处理程序中未处理的异常“参数不正确”
【发布时间】:2018-04-24 17:43:10
【问题描述】:

我有一个非常简单的ListView,其ItemsSourceObservableCollection。最好用代码来展示:

MainPage.xaml:

<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows.UI.Xaml.Shapes"
x:Class="Test.MainPage" Background="Black" >

<Grid x:Name="Board" Background="Transparent" >
    <ListView ItemsSource="{x:Bind LineList}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:Line">
                <StackPanel Orientation="Horizontal" Spacing="5">
                    <TextBlock Foreground="White" Text="{x:Bind Name}"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

Mainpage.xaml.cs:

public sealed partial class MainPage : Page
{
    public ObservableCollection<Line> LineList = new ObservableCollection<Line>();

    public MainPage()
    {
        InitializeComponent();
        LineList.CollectionChanged += List_CollectionChanged;
        LineList.Add(new Line { Name = "Line1" });
        LineList.Add(new Line { Name = "Line2" });
    }

    private void List_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if(e.Action == NotifyCollectionChangedAction.Add)
        {
            Board.Children.Add(e.NewItems[0] as Line);//if I comment out this line, no exception
        }
    }
}

我真正想要的是,当我在ListView 上添加Line 以显示它是Name 时,它也会作为实际Shape 添加到网格中。 请注意,我使用 ListView 仅显示这些行的名称,在网格中我想要一个实际的 Line 形状

我不知道我做错了什么,但上述尝试给出了声明的异常。

如果这些信息有帮助:

  1. 如果我不在Grid 中添加Line,不会出现异常
  2. 没有例外,如果:Board.Children.Add(new Line { Name = "Line2" });

【问题讨论】:

  • 什么是e.NewItems[0]?您在视图加载之前将项目添加到构造函数本身中,因此您可以检查项目或控件是否已形成。
  • 还有一点,为什么 LineList 不是公共访问器类型?
  • 好吧 LineList 现在是公开的,但它没有帮助
  • 让我直截了当地说,除了在ListView 中填充LineList 项之外,您还想在网格中添加另一个元素吗?
  • @Ale_lipa 我还想在网格中添加Line 元素,作为形状,它的名称在List

标签: c# exception uwp observablecollection


【解决方案1】:

我一直在摆弄您的代码,并且能够找出您的代码有什么问题。但是我不确定为什么会这样。

您收到错误的原因是因为您尝试使用与您的ListView.ItemsSource 绑定的UIElement(即Line)的相同实例。为什么它失败了,对我来说有点神秘。我怀疑禁止 Bind 并将相同的 UIElement 添加到 XAML,因为它可能会创建绑定循环!?不过,这只是一个疯狂的猜测。总之……

你不应该使用UIElement 作为绑定上下文——我想不出你会做这种事情的任何场景。根据我之前的回答(例如LineViewModel)创建一个单独的模型,并将其用作您的BindingContext,您会更好。您的 MainPage.xaml.cs 代码可能如下所示:

public sealed partial class MainPage : Page
{
    public ObservableCollection<LineViewModel> Lines = new ObservableCollection<LineViewModel>();

    public MainPage()
    {
        InitializeComponent();

        Lines.CollectionChanged += LinesOnCollectionChanged;
        Lines.Add(new LineViewModel { Name = "Line1" });
        Lines.Add(new LineViewModel { Name = "Line2" });
    }

    private void LinesOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            MainGrid.Children.Add(new Line()
            {
                Name = (e.NewItems[0] as LineViewModel)?.Name ?? string.Empty,
                Stroke = new SolidColorBrush(Colors.Black),
                StrokeThickness = 12,
                X1 = 0,
                X2 = 10000
            });
        }
    }
}

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

根据我之前的回答,MainPage.xaml 将保持不变

【讨论】:

    【解决方案2】:

    我不确定这是否是你所追求的,但它就是这样

    MainPage.xaml

    <Page x:Class="App4.MainPage"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:local="using:App4"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          mc:Ignorable="d">
        <Page.Resources>
            <Style x:Key="LineViewItemContainerStyle"
                   TargetType="ListViewItem">
                <Setter Property="FontFamily"
                        Value="{ThemeResource ContentControlThemeFontFamily}" />
                <Setter Property="FontSize"
                        Value="{ThemeResource ControlContentThemeFontSize}" />
                <Setter Property="Background"
                        Value="{ThemeResource ListViewItemBackground}" />
                <Setter Property="Foreground"
                        Value="{ThemeResource ListViewItemForeground}" />
                <Setter Property="TabNavigation"
                        Value="Local" />
                <Setter Property="IsHoldingEnabled"
                        Value="True" />
                <Setter Property="Padding"
                        Value="0" />
                <Setter Property="HorizontalContentAlignment"
                        Value="Stretch" />
                <Setter Property="VerticalContentAlignment"
                        Value="Stretch" />
                <Setter Property="MinWidth"
                        Value="{ThemeResource ListViewItemMinWidth}" />
                <Setter Property="MinHeight"
                        Value="{ThemeResource ListViewItemMinHeight}" />
                <Setter Property="AllowDrop"
                        Value="False" />
                <Setter Property="UseSystemFocusVisuals"
                        Value="True" />
                <Setter Property="FocusVisualMargin"
                        Value="0" />
                <Setter Property="FocusVisualPrimaryBrush"
                        Value="{ThemeResource ListViewItemFocusVisualPrimaryBrush}" />
                <Setter Property="FocusVisualPrimaryThickness"
                        Value="2" />
                <Setter Property="FocusVisualSecondaryBrush"
                        Value="{ThemeResource ListViewItemFocusVisualSecondaryBrush}" />
                <Setter Property="FocusVisualSecondaryThickness"
                        Value="1" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">
                            <ListViewItemPresenter x:Name="Root"
                                                   CheckBrush="{ThemeResource ListViewItemCheckBrush}"
                                                   ContentMargin="{TemplateBinding Padding}"
                                                   CheckBoxBrush="{ThemeResource ListViewItemCheckBoxBrush}"
                                                   ContentTransitions="{TemplateBinding ContentTransitions}"
                                                   CheckMode="{ThemeResource ListViewItemCheckMode}"
                                                   DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}"
                                                   DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
                                                   DragBackground="{ThemeResource ListViewItemDragBackground}"
                                                   DragForeground="{ThemeResource ListViewItemDragForeground}"
                                                   FocusVisualSecondaryBrush="{TemplateBinding FocusVisualSecondaryBrush}"
                                                   FocusVisualPrimaryThickness="{TemplateBinding FocusVisualPrimaryThickness}"
                                                   FocusVisualSecondaryThickness="{TemplateBinding FocusVisualSecondaryThickness}"
                                                   FocusBorderBrush="{ThemeResource ListViewItemFocusBorderBrush}"
                                                   FocusVisualMargin="{TemplateBinding FocusVisualMargin}"
                                                   FocusVisualPrimaryBrush="{TemplateBinding FocusVisualPrimaryBrush}"
                                                   FocusSecondaryBorderBrush="{ThemeResource ListViewItemFocusSecondaryBorderBrush}"
                                                   HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                   Control.IsTemplateFocusTarget="True"
                                                   PressedBackground="{ThemeResource ListViewItemBackgroundPressed}"
                                                   PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackground}"
                                                   PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}"
                                                   PointerOverBackground="{ThemeResource ListViewItemBackgroundPointerOver}"
                                                   ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}"
                                                   SelectedForeground="{ThemeResource ListViewItemForegroundSelected}"
                                                   SelectionCheckMarkVisualEnabled="{ThemeResource ListViewItemSelectionCheckMarkVisualEnabled}"
                                                   SelectedBackground="{ThemeResource ListViewItemBackgroundSelected}"
                                                   SelectedPressedBackground="{ThemeResource ListViewItemBackgroundSelectedPressed}"
                                                   SelectedPointerOverBackground="{ThemeResource ListViewItemBackgroundSelectedPointerOver}"
                                                   VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal" />
                                        <VisualState x:Name="Selected" />
                                        <VisualState x:Name="PointerOver">
                                            <VisualState.Setters>
                                                <Setter Target="Root.(RevealBrush.State)"
                                                        Value="PointerOver" />
                                            </VisualState.Setters>
                                        </VisualState>
                                        <VisualState x:Name="PointerOverSelected">
                                            <VisualState.Setters>
                                                <Setter Target="Root.(RevealBrush.State)"
                                                        Value="PointerOver" />
                                            </VisualState.Setters>
                                        </VisualState>
                                        <VisualState x:Name="PointerOverPressed">
                                            <VisualState.Setters>
                                                <Setter Target="Root.(RevealBrush.State)"
                                                        Value="Pressed" />
                                            </VisualState.Setters>
                                        </VisualState>
                                        <VisualState x:Name="Pressed">
                                            <VisualState.Setters>
                                                <Setter Target="Root.(RevealBrush.State)"
                                                        Value="Pressed" />
                                            </VisualState.Setters>
                                        </VisualState>
                                        <VisualState x:Name="PressedSelected">
                                            <VisualState.Setters>
                                                <Setter Target="Root.(RevealBrush.State)"
                                                        Value="Pressed" />
                                            </VisualState.Setters>
                                        </VisualState>
                                    </VisualStateGroup>
                                    <VisualStateGroup x:Name="DisabledStates">
                                        <VisualState x:Name="Enabled" />
                                        <VisualState x:Name="Disabled">
                                            <VisualState.Setters>
                                                <Setter Target="Root.RevealBorderThickness"
                                                        Value="0" />
                                            </VisualState.Setters>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                            </ListViewItemPresenter>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Page.Resources>
    
        <Grid Background="Transparent">
            <ListView ItemContainerStyle="{StaticResource LineViewItemContainerStyle}"
                      ItemsSource="{x:Bind Lines, Mode=OneTime}"
                      HorizontalContentAlignment="Stretch"
                      VerticalContentAlignment="Stretch">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="local:LineViewModel">
                        <Grid x:Name="ItemGrid">
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <TextBlock Foreground="Black"
                                       Text="{x:Bind Name, Mode=OneWay}" />
                            <Border Grid.Row="1"
                                    BorderBrush="Black"
                                    BorderThickness="1" />
                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </Page>
    

    MainPage.xaml.cs

    public sealed partial class MainPage : Page
    {
        public ObservableCollection<LineViewModel> Lines = new ObservableCollection<LineViewModel>();
    
        public MainPage()
        {
            InitializeComponent();
    
            Lines.Add(new LineViewModel { Name = "Line1" });
            Lines.Add(new LineViewModel { Name = "Line2" });
        }
    }
    
    public class LineViewModel
    {
        public string Name { get; set; }
    }
    

    请注意,我没有使用Line,而是使用了Border。另外,我需要覆盖基本ListViewItemContainerStyle 以将HorizontalContentAlignmentVerticalContentAlignment 设置为Stretch,以便DataTemplate 元素可以占据项目的整个空间

    结果:

    【讨论】:

    • 感谢您的回答,但这不是我想要的。我已经更新了问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 2013-09-22
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多