【问题标题】:DataGrid data binding and MVVM in WPFWPF 中的 DataGrid 数据绑定和 MVVM
【发布时间】:2020-09-27 03:36:10
【问题描述】:

一个包含DataGridWindow 的WPF 应用程序,试图实现MVVM 架构。有一个模型类:

public class Book
{
    public int id {get; set;}
    public string title {get; set;}
    public string isbn {get; set;}
}

这是视图模型:

class BookViewModel
{
    public ObservableCollection<Book> Books;

    public BookViewModel()
    {
        Books = new ObservableCollection<Book>();

        // TODO: execute LoadData comand
    }
}

用于标记视图的 XAML 代码的部分 sn-p,由单个窗口组成:

<Window.CommandBindings>
    <CommandBinding Command="self:CustomCommands.LoadData" CanExecute="LoadDataCommand_CanExecute" Executed="LoadDataCommand_Executed"/>
</Window.CommandBindings>

<DataGrid Name="BooksDataGrid>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Title" Width="200" Binding="{Binding title}"/>
        <DataGridTextColumn Header="isbn" Width="200" Binding="{Binding isbn}"/>
    </DataGrid.Columns>
</DataGrid>

上面视图的代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // TODO: execute LoadData command
    }

    private void LoadDataCommand_CanExecute(object sender, CanExecuteRoutedEventArgs args)
    {
        args.CanExecute = true;
    }

    private void LoadDataCommand_Executed(object sender, ExecutedRoutedEventArgs args)
    {
       // TODO: ask the model for the data
    }
}

public static class CustomCommands
{
    public static readonly RoutedUICommand LoadData = new RoutedUICommand
        (
            "LoadData",
            "LoadData",
            typeof(CustomCommands),
            new InputGestureCollection()
            {
                // allow Ctrl+L to perform this command
                new KeyGesture(Key.L, ModifierKeys.Control)
            }
        );
}

App.xaml 的代码隐藏:

public partial class App : Application
{
    [STAThread()]
    public static void Main()
    {
        App app = new App();
        app.InitializeComponent();
        app.Run();
    }

    // bind application and show main window on startup
    // data context is default source of bindings
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        View.MainWindow mainWin = new View.MainWindow();
        ViewModel.BookViewModel bookViewModel = new ViewModel.BookViewModel();
        mainWin.DataContext = bookViewModel;
        mainWin.Show();
    }
}

我正在从 WinForms 过渡到 WPF,并且发现 WPF 的某些方面令人困惑。试图实现的目标和面临的问题如下:

  • LoadData 命令应该清除GridView,然后从数据库中再次填充它。数据库连接已经实现。到目前为止,我还看不出如何让数据绑定工作。
  • LoadData 命令应同时从菜单和按钮执行(已实现)。
  • LoadData 命令应该在应用程序启动时执行。这样DataGrid 在启动时就会被填充。

【问题讨论】:

  • 你为什么在Window代码后面而不是视图模型中编写代码?
  • @PavelAnikhouski 跟随教程。
  • 是什么让你认为这是 MVVM...?

标签: c# wpf mvvm data-binding observablecollection


【解决方案1】:

第一步:您创建了一个窗口及其视图模型,并通过 DataContext 将它们连接起来。已经完成了

View.MainWindow mainWin = new View.MainWindow();
ViewModel.BookViewModel bookViewModel = new ViewModel.BookViewModel();
mainWin.DataContext = bookViewModel;

第二步:修复(添加)xaml 中的绑定:

<DataGrid Name="BooksDataGrid" ItemsSource="{Binding Books}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Title" Width="200" Binding="{Binding title}"/>
        <DataGridTextColumn Header="isbn" Width="200" Binding="{Binding isbn}"/>
    </DataGrid.Columns>
</DataGrid>

第三步:修复视图模型以使绑定工作 - 绑定与属性一起工作:

class BookViewModel
{
    public ObservableCollection<Book> Books { get; private set; }

    public BookViewModel()
    {
        Books = new ObservableCollection<Book>();
    }
}

第四步:在视图模型中实现加载数据方法并从命令中调用,在mainWin.Show();之后加载初始数据

【讨论】:

  • 最有帮助的答案。问题是 ObservableCollection 不是属性。
【解决方案2】:

除了初始化组件和设置数据上下文之外,窗口的代码隐藏中不应有太多代码。

public MainWindow()
{
   IntializeComponent();
   DataContext = new BookViewModel();
}

您的 loadData 命令将在 BookViewModel 中实现

private bool _canLoadDataExecute;
private ICommand _loadDataCommand;
public Icommand LoadDataCommand => _loadDataCommand ?? _loadDataCommand = new RelayCommand((obj) => LoadDataCommand = LoadData(), canLoadDataExecute);

public void LoadData()
{
}

要使上述代码正常工作,您还需要实现 RelayCommand.cs,可以在此处找到相关代码:Full implementation of Relay Command - can it be applied to all cases?。此外,还有许多其他关于 RelayCommand 实施的有用答案和在线资源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 2018-02-07
    • 1970-01-01
    • 2017-08-20
    • 2013-03-24
    • 2015-05-24
    • 1970-01-01
    相关资源
    最近更新 更多