我发现我的问题很奇怪。

我有一个使用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>

以下代码更好,它使您可以根据WidthHeight的显示以及WindowUserControl来查看所有要查看的项目并调整大小:
   <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不显示最后一条记录-LMLPHP

关于wpf - WPF MVVM ListBox不显示最后一条记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36577634/

10-12 01:34
查看更多