我发现我的问题很奇怪。
我有一个使用MVVM模式的WPF应用程序。
我使用Linq-to-SQL从数据库中检索数据,并使用绑定(bind)在ListBox中显示Description字段数据。
它有效,但不完全。由于某种原因,最后的记录不显示。我已经验证了它是从数据库中获取的。不能选择;它根本不存在。
使记录出现的唯一方法是将焦点设置在ListBox上,或者滚动鼠标滚动器,或者实际上使用键盘向下移动以超过最后一条记录(应该是第二条最后一条记录)。完成后,将显示记录。
使记录显示出来的另一种方法是更新ListBox中的任何记录。我有一个以双向方式绑定(bind)到ListBox的SelectedItem的TextBox,所以当我选择一个项目时,更改TextBox中的文本并单击Update按钮,它会调用Command进行数据库更新,效果很好,但是还会显示最后一条记录的缺失记录。
因为我都尝试了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);
}
}
}
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);
}
}
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>
以下代码更好,它使您可以根据
Width
或Height
的显示以及Window
和UserControl
来查看所有要查看的项目并调整大小: <Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="2*"/>
</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 class FooClass
{
public string Description { get; set; }
}
而且我已经在循环中填充了
ListView
: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;
}
XAML:
<ListView x:Name="LstCategories" 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>
结果是:
关于wpf - WPF MVVM ListBox不显示最后一条记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36577634/