WPF MVVM列表框不显示最后一条记录

WPF MVVM列表框不显示最后一条记录,wpf,xaml,mvvm,listbox,Wpf,Xaml,Mvvm,Listbox,我发现我遇到的问题很奇怪 我有一个使用MVVM模式的WPF应用程序 我使用Linq to SQL从数据库检索数据,并使用绑定在列表框中显示描述字段数据 它是有效的,但并不完全有效。由于某些原因,最后一条记录不显示。我已经确认它是从数据库中提取的。不可选择;它根本不在那里 让记录显示的唯一方法是将焦点设置到列表框,滚动鼠标滚动条或使用键盘向下移动,以越过最后一条记录(这应该是第二条最后一条记录)。一旦您这样做,记录就会出现 另一种显示记录的方法是更新列表框中的任何记录。我有一个双向模式的文本框绑定

我发现我遇到的问题很奇怪

我有一个使用MVVM模式的WPF应用程序

我使用Linq to SQL从数据库检索数据,并使用绑定在列表框中显示描述字段数据

它是有效的,但并不完全有效。由于某些原因,最后一条记录不显示。我已经确认它是从数据库中提取的。不可选择;它根本不在那里

让记录显示的唯一方法是将焦点设置到列表框,滚动鼠标滚动条或使用键盘向下移动,以越过最后一条记录(这应该是第二条最后一条记录)。一旦您这样做,记录就会出现

另一种显示记录的方法是更新列表框中的任何记录。我有一个双向模式的文本框绑定到列表框的SelectedItem,因此当我选择一个项目时,更改文本框中的文本并单击Update按钮,它调用命令来进行数据库更新,这很好,但最后一条记录的缺失记录也会显示出来

ListBox和ListView是否存在渲染问题,因为我已经尝试了这两种方法?为什么列表框似乎需要在最后一个项目出现之前“重新绘制”

CategoryModel.cs

public class CategoryModel
{
    public int CategoryID { get; set; }
    public string Description { get; set; }

    public List<CategoryModel> categories = new List<CategoryModel>();
    readonly SalesLinkerDataContext _dbContext = new SalesLinkerDataContext();

    public void GetCategories()
    {
        categories.Clear();

        var result = _dbContext.tblSalesCategories.ToList();

        foreach (var item in result)
        {
            categories.Add(new CategoryModel
            {
                CategoryID = item.CategoryID,
                Description = item.Description.Trim()
            });
        }
    }

    internal void Update(CategoryModel cm)
    {
        try
        {
            var category = (from a in _dbContext.tblSalesCategories
                where a.CategoryID == cm.CategoryID
                select a).FirstOrDefault();

            if (category != null)
            {
                category.Description = cm.Description;
                _dbContext.SubmitChanges();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
}
公共类类别模型
{
public int CategoryID{get;set;}
公共字符串说明{get;set;}
公共列表类别=新列表();
只读SalesLinkedDataContext _dbContext=new SalesLinkedDataContext();
公共类别()
{
类别。清除();
var result=_dbContext.tblSalesCategories.ToList();
foreach(结果中的var项目)
{
类别。添加(新类别模型)
{
CategoryID=item.CategoryID,
Description=item.Description.Trim()
});
}
}
内部作废更新(类别模型cm)
{
尝试
{
var category=(来自_dbContext.tblSalesCategories中的
其中a.CategoryID==cm.CategoryID
选择一个.FirstOrDefault();
如果(类别!=null)
{
类别描述=厘米描述;
_dbContext.SubmitChanges();
}
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message);
}
}
}
CategoriesViewModel.cs

public class CategoriesViewModel : ViewModelBase, IPageViewModel
{
    public CategoryModel Categories = new CategoryModel();

    private DelegateCommand _getCategoriesCommand;
    private DelegateCommand _updateCategoryCommand;


    /// <summary>
    /// Describes the name that will be used for the menu option
    /// </summary>
    public string Name
    {
        get { return "Manage Categories"; }  

    }

    public string Description
    {
        get { return Categories.Description; }
        set
        {
            Categories.Description = value;
            OnPropertyChanged("Description");
        }
    }

    public List<CategoryModel> ReceivedCategories
    {
        get { return Categories.categories; }

        set
        {
            Categories.categories = value;
            OnPropertyChanged("ReceivedCategories");
        }
    }

    public ICommand GetCategoriesCommand
    {
        get
        {
            if (_getCategoriesCommand == null)
            {
                _getCategoriesCommand = new DelegateCommand(GetCategories, CanGetCategories);
            }

            return _getCategoriesCommand;
        }   
    }

    private bool CanGetCategories()
    {
        return true;
    }

    private void GetCategories()
    {
        Categories.GetCategories();
        ReceivedCategories = Categories.categories;

    }

    public ICommand UpdateCategoryCommand
    {
        get
        {
            if (_updateCategoryCommand == null)
            {
                _updateCategoryCommand = new DelegateCommand(UpdateCategory, CanUpdateCategory);
            }

            return _updateCategoryCommand;
        }


    }

    private bool CanUpdateCategory()
    {
        return true;
    }

    private void UpdateCategory()
    {

        Categories.Update(Categories);
    }

}
公共类分类ViewModel:ViewModelBase,IPageViewModel { public CategoryModel Categories=new CategoryModel(); 专用DelegateCommand_getCategoriesCommand; 私有DelegateCommand_updateCategoryCommand; /// ///描述将用于菜单选项的名称 /// 公共字符串名 { 获取{返回“管理类别”;} } 公共字符串描述 { 获取{return Categories.Description;} 设置 { 类别。描述=值; 不动产变更(“说明”); } } 收到的公共目录类别 { 获取{return Categories.Categories;} 设置 { 类别。类别=价值; 关于财产变更(“接收类别”); } } 公共ICommand GetCategoriesCommand { 得到 { if(_getCategoriesCommand==null) { _getCategoriesCommand=新的DelegateCommand(GetCategories,CanGetCategories); } 返回_getCategoriesCommand; } } 私人bool CanGetCategories() { 返回true; } 私有类别() { Categories.GetCategories(); ReceivedCategories=Categories.Categories; } 公共ICommand updateCategory命令 { 得到 { if(_updateCategoryCommand==null) { _updateCategoryCommand=新的DelegateCommand(UpdateCategory,CanUpdateCategory); } 返回_updatecategory命令; } } 私有布尔CanUpdateCategory() { 返回true; } 私有void UpdateCategory() { 类别。更新(类别); } } CategoriesView.xaml

<UserControl x:Class="SalesLinker.CategoriesView"
  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:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
  mc:Ignorable="d" 
  d:DesignHeight="300" d:DesignWidth="600" Background="White" >

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <i:InvokeCommandAction Command="{Binding GetCategoriesCommand}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

<Grid >
    <Grid.RowDefinitions>
        <RowDefinition Height="45"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="250"/>
        <ColumnDefinition Width="100"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Label Grid.Row="0" Grid.Column="0" Margin="20,0,0,0" FontSize="20" HorizontalAlignment="Center" Content="Categories"/>
    <ListView x:Name="LstCategories" ItemsSource="{Binding ReceivedCategories, Mode=TwoWay}" Grid.Column="0" Grid.Row="1" 
              VerticalAlignment="Stretch"
              Background="LightGray"
              ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
              SelectionChanged="LstCategories_OnSelectionChanged">

        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" >
                    <TextBlock Text="{Binding Description }"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

    <Button Command="{Binding AddCategoryCommand}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Height="50" Width="50" Margin="0,20,0,0" Background="Transparent" BorderThickness="0" BorderBrush="Transparent" >
        <Image Source="/Images/Plus.png"/>
    </Button>
    <Button Command="{Binding RemoveCategoryCommand}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Height="50" Width="50" Margin="0,75,0,0" Background="Transparent" BorderThickness="0">
        <Image Source="/Images/Minus.png"/>
    </Button>

    <Grid Grid.Row="1" Grid.Column="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="75"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Label VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="0" Content="Description:"/>

        <TextBox DataContext="CategoryModel" Grid.Row="0" Grid.Column="1" Width="250" Height="Auto" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0" 
                 Text="{Binding SelectedItem.Description, ElementName=LstCategories}"/>


        <Button Command="{Binding UpdateCategoryCommand}" 
                Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Margin="10,0,0,0" Height="20" Width="120" Content="Update Description"/>

    </Grid>
</Grid>

我对MVVM非常陌生,所以希望我没有看到简单的东西。

由于某些原因,最后一条记录没有显示出来。我已经确认它是从数据库中提取的

若您从数据库中获取所有数据,那个么可以得出结论,您无法看到最后一项的原因是因为您使用了不正确的布局。我是说静态布局

我建议您使用动态布局,而不是静态布局。我的意思是这很糟糕:

<Grid.RowDefinitions>
    <RowDefinition Height="45"/>
    <RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="250"/>
    <ColumnDefinition Width="100"/>
    <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
让我举一个完整的例子:

<Grid>
  <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <Label Grid.Row="0" Grid.Column="0" Margin="20,0,0,0" FontSize="20" HorizontalAlignment="Center" Content="Categories"/>
    <ListView x:Name="LstCategories" ItemsSource="{Binding ReceivedCategories, Mode=TwoWay}" Grid.Column="0" Grid.Row="1" 
          VerticalAlignment="Stretch"
          Background="LightGray"
          ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" >
                    <TextBlock Text="{Binding Description }"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>

    </ListView>

    <Button Command="{Binding AddCategoryCommand}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Height="50" Width="50" Margin="0,20,0,0" Background="Transparent" BorderThickness="0" BorderBrush="Transparent" >
        <Image Source="/Images/Plus.png"/>
    </Button>
    <Button Command="{Binding RemoveCategoryCommand}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Height="50" Width="50" Margin="0,75,0,0" Background="Transparent" BorderThickness="0">
        <Image Source="/Images/Minus.png"/>
    </Button>

    <Grid Grid.Row="1" Grid.Column="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1.5*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>

        <Label VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="0" Content="Description:"/>

        <TextBox DataContext="CategoryModel" Grid.Row="0" Grid.Column="1" Height="Auto" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0" 
             Text="{Binding SelectedItem.Description, ElementName=LstCategories}"/>


        <Button Command="{Binding UpdateCategoryCommand}" 
            Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Content="Update Description"/>
</Grid>
我已经在一个循环中填充了您的
列表视图

public MainWindow()
{
   InitializeComponent();
   PopulateCollection();
}

private void PopulateCollection()
{
   List<FooClass> fooColl = new List<FooClass>();
   for (int i = 0; i <= 1000; i++)
   {
      fooColl.Add(new FooClass() { Description=i.ToString()});
   }
   LstCategories.ItemsSource = fooColl;       
}
public主窗口()
{
初始化组件();
PopulateCollection();
}
私有void PopulateCollection()
{
List fooColl=新列表();
对于(int i=0;i由于某种原因,最后一条记录不会显示。我已验证它是从数据库中获取的

若您从数据库中获取所有数据,那个么可以得出结论,为什么您不能看到最后一项是因为您使用了不正确的布局。我指的是静态布局

我建议您使用动态布局,而不是静态布局。我的意思是这很糟糕:

<Grid.RowDefinitions>
    <RowDefinition Height="45"/>
    <RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
    <ColumnDefinition Width="250"/>
    <ColumnDefinition Width="100"/>
    <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
让我举一个完整的例子:

<Grid>
  <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="2*"/>
        <ColumnDefinition Width="2*"/>
    </Grid.ColumnDefinitions>
    <Label Grid.Row="0" Grid.Column="0" Margin="20,0,0,0" FontSize="20" HorizontalAlignment="Center" Content="Categories"/>
    <ListView x:Name="LstCategories" ItemsSource="{Binding ReceivedCategories, Mode=TwoWay}" Grid.Column="0" Grid.Row="1" 
          VerticalAlignment="Stretch"
          Background="LightGray"
          ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch" >
                    <TextBlock Text="{Binding Description }"/>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>

    </ListView>

    <Button Command="{Binding AddCategoryCommand}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Height="50" Width="50" Margin="0,20,0,0" Background="Transparent" BorderThickness="0" BorderBrush="Transparent" >
        <Image Source="/Images/Plus.png"/>
    </Button>
    <Button Command="{Binding RemoveCategoryCommand}" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Height="50" Width="50" Margin="0,75,0,0" Background="Transparent" BorderThickness="0">
        <Image Source="/Images/Minus.png"/>
    </Button>

    <Grid Grid.Row="1" Grid.Column="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1.5*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>

        <Label VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="0" Grid.Column="0" Content="Description:"/>

        <TextBox DataContext="CategoryModel" Grid.Row="0" Grid.Column="1" Height="Auto" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0" 
             Text="{Binding SelectedItem.Description, ElementName=LstCategories}"/>


        <Button Command="{Binding UpdateCategoryCommand}" 
            Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" Content="Update Description"/>
</Grid>
我已经在一个循环中填充了您的
列表视图

public MainWindow()
{
   InitializeComponent();
   PopulateCollection();
}

private void PopulateCollection()
{
   List<FooClass> fooColl = new List<FooClass>();
   for (int i = 0; i <= 1000; i++)
   {
      fooColl.Add(new FooClass() { Description=i.ToString()});
   }
   LstCategories.ItemsSource = fooColl;       
}
public主窗口()
{
初始化组件();
PopulateCollection();
}
私有void PopulateCollection()
{
List fooColl=新列表();
对于(int i=0;i代码