NotifyCollectionChangedEvent处理程序中未处理的异常`参数不正确`

时间:2018-04-22 17:16:58

标签: c# exception uwp observablecollection

我有一个非常简单ListViewItemsSourceObservableCollection。最好用代码展示它:

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
        }
    }
}

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

我不知道自己做错了什么,但上述尝试给出了规定的例外情况。

如果这些信息有帮助:

  1. 如果我未在Line
  2. 中添加Line,则不会发生异常
  3. 如果出现以下情况:Grid

2 个答案:

答案 0 :(得分:1)

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

您收到错误的原因是因为您尝试使用与UIElement绑定的Line(即ListView.ItemsSource)的相同实例。为什么它失败了,对我来说有点神秘。我怀疑它被禁止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 将保持不变

答案 1 :(得分:0)

我不确定这是否属于您之后但又来了

<强> 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元素占用项目的整个空间

结果:

enter image description here