【问题标题】:C# inheritance at the constructor using base and MVVM communication使用基本和 MVVM 通信在构造函数处继承 C#
【发布时间】:2024-01-24 04:01:03
【问题描述】:

我正在使用基于 SDK 示例的 Telerik WPF 控件构建 GUI。注意:WPF 对我来说是新的,我对 C# 有点生疏。

*问题:当我从远程数据库加载数据时,我正在尝试使用 RadBusyIndi​​cator 显示繁忙指示器。我知道我需要使用后台工作人员来让 GUI 保持响应,但是一旦我了解对象之间的通信实际上是如何工作的,我就可以处理这个问题。我不明白的具体行是在ReportsViewModel 构造函数中关于在base 方法中使用GeotechWindow 的实例。


一、xaml代码:

<Window x:Class="PSE.GeotechLog.WPF.Views.GeotechWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"      
    xmlns:local ="clr-namespace:PSE.GeotechLog.WPF.Views">

    <telerik:RadBusyIndicator x:Name="GeotechBusyIndicator">
        <Grid>
            <telerik:RadGridView x:Name="GeotechGrid"
                ItemsSource="{Binding Path=ReportsToDisplay, Mode=OneWay}">
                <!-- some content -->
            </telerik:RadGridView>
        </Grid>
    </telerik:RadBusyIndicator>
</Window>

窗口后面的代码:

namespace PSE.GeotechLog.WPF.Views
{
    public partial class GeotechWindow : Window, IMainView
    {
        public GeotechWindow()
        {
            InitializeComponent();
        }
    }
}

实例化我的窗口的 ViewModel(不知何故 - 我不明白 base 一词的使用或类定义和构造函数之间的多重继承):

namespace PSE.GeotechLog.WPF.ViewModels
{
    public class ReportsViewModel : ViewModelBase<IMainView>, IDisposable
    {
        private readonly GeotechLogContext context;
        private List<GeotechReport> reportsToDisplay;

        public ReportsViewModel() : base( new GeotechWindow() )
        {
            this.context= new GeotechLogContext();            
            // enable busy indicator
            this.ReportsToDisplay = this.context.GeotechReports.ToList();
            // disable busy indicator
        }
        public List<GeotechReport> ReportsToDisplay
        {
            get { return this.reportsToDisplay; }
            private set
            {
                this.reportsToDisplay = value;
                this.RaisePropertyChanged("ReportsToDisplay");
            }
        }
    }
}

最后是应用入口代码。注意:我添加了 newint 变量以查看如何从 ReportsViewModel 实例访问某些内容,但我从来没有看到访问它,这表明我的理解存在根本差距。

namespace PSE.GeotechLog.WPF
{
    public partial class App : Application
    {
        private ReportsViewModel geotechLogViewModel;
        public int newint;
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            this.geotechLogViewModel = new ReportsViewModel();
            this.geotechLogViewModel.Show();    
        }
    }
}

我不明白的地方:如何使用ReportsViewModel 对象中的RadBusyIndi​​cator 对象GeotechBusyIndicator?顺便说一句,我如何在派生类中访问newint?我认为这是同一个问题,但我可能是错的。我重写了很多代码,而且我已经这样做了很多天,但是由于 MVVM 抽象技术,在这种情况下使用继承让我彻底困惑。任何帮助将不胜感激。

【问题讨论】:

  • 通常你不会直接从视图模型中与视图对话。视图模型只是通过公开诸如IsBusy 之类的属性来抽象概念,并且忙碌指示符绑定到视图模型上的IsBusy 属性。视图模型和绑定系统中的IsBusy 属性更改(通过INotifyPropertyChange)通知视图某些绑定发生了更改。视图会自动更新以响应这些通知。基本上视图模型是逻辑/数据,视图是视图模型的可视化表示,绑定系统将两者粘合在一起
  • 我认为您对继承感到困惑。 c# 不支持多重继承。 ReportViewModel 继承自 ViewModelBase&lt;T&gt;GeotechWindow 继承自 Window。超类型之后的任何其他类型都是接口而不是类。 ReportsViewModel 上的类构造函数通过base 关键字调用超级构造函数——传入一个新的GeotechWindow 实例(实现IMainView)。它基本上只是用您指定为IMainView的泛型类型T 的实例初始化ViewModelBase&lt;T&gt;
  • base 总是引用当前实例超类型,就像this 总是引用当前实例一样
  • 听起来比实际情况更糟——你有其他语言的背景吗?也许我可以给你 C# 中的等价物
  • 值得一看:msdn.microsoft.com/en-US/library/ms173149(v=vs.80).aspx - 它对继承的所有特性进行了简单而简洁的概述。在左侧菜单中查看该页面及其下的任何主题

标签: c# wpf inheritance mvvm telerik


【解决方案1】:

感谢 Charleh 朝着正确的方向前进。因为 MVVM 对我来说太陌生了,我什至没有意识到这是与忙碌指示器进行通信的明显方式。

将此添加到 xaml:

&lt;telerik:RadBusyIndicator x:Name="GeotechBusyIndicator" IsBusy="{Binding Path=GridBusy, Mode=OneWay}"&gt;

这个给 ViewModel:

private bool gridBusy;
public bool GridBusy
{
    get { return this.gridBusy; }
    set
    {
        this.gridBusy = value;
        this.RaisePropertyChanged("GridBusy");
    }
}

解决了这个问题。现在我必须将数据上下文加载包装在后台工作程序中,我应该很好。

【讨论】: