将用户控件与数据网格一起使用时,在使用ItemsSource之前,Items集合必须为空

时间:2019-05-24 13:13:41

标签: c# wpf

我有一个例外:ItemsItemsSource一起使用时,UserControl集合必须为空,然后再使用DataGrid

  <Window.Resources>
        <DataTemplate DataType="{x:Type login:LoginViewModel}">
            <login:LoginView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type customers:CustomerListViewModel}">
            <customers:CustomerListView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type customers:CustomerDetailsViewModel}">
            <customers:CustomerDetailsView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type customers:CustomerItemsViewModel}">
            <customers:CustomerItemsView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type finishedProductLots:FinishedProductListViewModel}">
            <finishedProductLots:FinishedProductListView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type finishedProductLots:FinishedProductLotDetailViewModel}">
            <finishedProductLots:FinishedProductLotDetailView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type supplierLots:SupplierLotListViewModel}">
            <supplierLots:SupplierLotListView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type supplierLots:SupplierLotDetailViewModel}">
            <supplierLots:SupplierLotDetailView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type Users:UserViewModel}">
            <Users:UserView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type InternalLot:InternalLotListViewModel}">
            <InternalLot:InternalLotListView />
        </DataTemplate>
    </Window.Resources>

<Grid Grid.Column="0" Grid.Row="1" MinHeight="20">
            <ContentControl Name="Content" Content="{Binding CurrentViewModel}"/>
        </Grid>

通过此设置,我可以通过设置属性CurrentViewModel来在主窗口中的后面代码中更改视图。

现在,我有了一个想法,创建一个仅带有DataGrid(和搜索功能)的视图模型,我可以在整个应用程序中重复使用该模型。

所以我创建了一个UserControl

<UserControl x:Class="CustomerTracebility.UI.InternalLot.InternalLotListView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:CustomerTracebility.UI.InternalLot"
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <ei:CallMethodAction TargetObject="{Binding}" MethodName="LoadInternalLots" />
    </i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Row="0">
        <StackPanel Orientation="Horizontal">
            <Label Content="Lotnumber"></Label>
            <!--<TextBox MinWidth="100" Text="{Binding LotFilterValue}"></TextBox>-->
            <Button Content="Apply"></Button>
        </StackPanel>
    </Grid>
    <Grid Grid.Row="1">
        <DataGrid ItemsSource="{Binding InternalLots}"
                  AutoGenerateColumns="False"
                  CanUserAddRows="False" 
                  IsReadOnly="True"
                 >
            <!--<DataGrid.InputBindings>
                <MouseBinding MouseAction="LeftDoubleClick"
                              Command="{Binding Path=ViewFinishedProductLotCommand}"
                              CommandParameter="{Binding SelectedFinishedProductLot}" />
            </DataGrid.InputBindings-->>
            <!--<DataGrid.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="View"  
                              Command="{Binding DataContext.ViewFinishedProductLotCommand, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"
                              CommandParameter="{Binding SelectedFinishedProductLot}"/>
                    <MenuItem Header="Trace"  
                              Command="{Binding DataContext.TraceCommand, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"
                              CommandParameter="{Binding SelectedFinishedProductLot}"/>
                    <MenuItem Header="Transmit"
                              CommandParameter="{Binding ElementName=fpLotDataGrid, Path=SelectedItems}"
                              Command="{Binding DataContext.SendCommand, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"
                              ToolTip="Send the selected batches to the customer(s)"/>
                    --><!--CommandParameter="{Binding ElementName=fpLotDataGrid, Path=SelectedItems}"--><!--
                </ContextMenu>-->
            <!--</DataGrid.ContextMenu>-->
            <DataGrid.Columns>
                <!-- &#x0a; -->
                <DataGridTextColumn Binding="{Binding LotNumber}"
                                    Width="*"
                                    Header="Lot&#x0a;Number"
                                    />
                <DataGridTextColumn Binding="{Binding ItemNumber}"
                                    Width="*"
                                    Header="Item&#x0a;Number" 
                                    />
                <DataGridTextColumn Binding="{Binding Item.Description}"
                                    Width="*"
                                     Header="Item Description" />
                <DataGridTextColumn Binding="{Binding ExpiryDate, StringFormat='dd-MM-yyyy'}"
                                    Width="*"
                                    Header="Expiry&#x0a;Date"/>
                <DataGridTextColumn Binding="{Binding HarvestDate, StringFormat='dd-MM-yyyy'}"
                                    Width="*"
                                    Header="Harvest&#x0a;Date" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Grid>

我尝试从其他用户控件中调用它

<UserControl x:Class="CustomerTracebility.UI.FinishedProductLots.FinishedProductLotDetailView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:CustomerTracebility.UI.FinishedProductLots"
             mc:Ignorable="d" 
             d:DesignHeight="600" d:DesignWidth="600">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
            <Grid Grid.Row="7">
            <ContentControl Name="Content" Content="{Binding InternalLotListViewModel}"/>
        </Grid>

    </Grid>
</UserControl>

后面的代码

 private ObservableCollection<Lot> _InternalLots;
        public ObservableCollection<Lot> InternalLots
        {
            get { return _InternalLots; }
            set { SetProperty(ref _InternalLots, value); }
        }
        public async void LoadInternalLots()
        {
            List<Lot> list;

            if (this.LotFilterValue == string.Empty)
            {
                list = await this.lotBll.GetLotNumbersWithFilter();

            }else
            {
                list = await this.LotBll.GetLotNumbersWithFilter(this.LotFilterValue);
            }

            if(list.Count > 33)
            {
                this.InternalLots = new ObservableCollection<Lot>();
                foreach (var i in list.GetRange(0, 33))
                {
                    InternalLots.Add(i);
                }
                //this.InternalLots = new ObservableCollection<Lot>();
            }
            else
            {
                this.InternalLots = new ObservableCollection<Lot>();
                foreach (var i in list)
                {
                    InternalLots.Add(i);
                }
            }
        }

回顾一下:

我的主窗口有UserControl,该代码位于后面的代码中。该视图的Xmal中的UserControl的设置方法相同。 (加载的函数在加载控件时触发)。但是,当我填满可观察的集合时,我得到的错误Items集合必须为空,然后才能使用ItemsSource

我一直在寻找我的错误,但是我找不到它,而且我真的不知道在哪里寻找...

1 个答案:

答案 0 :(得分:2)

您的代码示例中>之后有一个额外的</DataGrid.InputBindings-->。尝试摆脱所有XAML注释,并确保<DataGrid><DataGrid.Columns>元素之间没有任何内容。