我正在使用 DevExpres WPF 组件并尝试创建一个简单的 WPF-only 项目。 文档说Winow应该从
MvxWindow
继承,UserControl从MvxWpfView
继承。
不幸的是,Devexpess 组件已经继承自 Window/etc 并且无法使用该方法。
关于可能的解决方案的唯一通知是文档中的简短说明,Windows 应该“包装在演示者中”,没有任何细节:)
Mvvm交叉:
public partial class MainWindow : MvxWindow
{
public MainWindow()
{
InitializeComponent();
}
}
<views:MvxWindow
x:Class="TipCalc.WPF.MainWindow"
xmlns:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</views:MvxWindow>
开发速递:
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : ThemedWindow
{
public MainWindow()
{
InitializeComponent();
}
}
<dx:ThemedWindow
x:Class="DevExpressMvvmCross.MainWindow"
Title="MainWindow" Height="350" Width="525" ShowStatusPanel="False">
<Grid>
</Grid>
</dx:ThemedWindow>
MvvmCross 可以使用外部组件吗?由于主题和其他 cookie,我想继续使用 dx 组件。
从技术上讲,您可以使用其他组件。由于 MVVM Cross 是开源的,您可以在没有 nuget 的情况下手动获取库并将它们附加到解决方案,从而允许您添加更多文件并在需要的地方扩展其功能。
为了将 MVVMCross 与 Devexpress 一起使用,您应该创建一个类来包装 Devexpress 的 ThemedWindow 并实现 MVVMCross 的三个接口。 IMvxWindow、IMvxWpfView、IDisposable。您可以复制 MvxWindow 类的实现。你的包装类可能看起来像这样:
public class DevexpressMvxWindow : ThemedWindow, IMvxWindow, IMvxWpfView, IDisposable
{
private IMvxViewModel _viewModel;
private IMvxBindingContext _bindingContext;
private bool _unloaded = false;
public IMvxViewModel ViewModel
{
get => _viewModel;
set
{
_viewModel = value;
DataContext = value;
BindingContext.DataContext = value;
}
}
public string Identifier { get; set; }
public IMvxBindingContext BindingContext
{
get
{
if (_bindingContext != null)
return _bindingContext;
if (Mvx.IoCProvider != null)
this.CreateBindingContext();
return _bindingContext;
}
set => _bindingContext = value;
}
public DevexpressMvxWindow()
{
Closed += MvxWindow_Closed;
Unloaded += MvxWindow_Unloaded;
Loaded += MvxWindow_Loaded;
Initialized += MvxWindow_Initialized;
}
private void MvxWindow_Initialized(object sender, EventArgs e)
{
if (this == Application.Current.MainWindow)
{
(Application.Current as MvvmCross.Platforms.Wpf.Views.MvxApplication).ApplicationInitialized();
}
}
private void MvxWindow_Closed(object sender, EventArgs e) => Unload();
private void MvxWindow_Unloaded(object sender, RoutedEventArgs e) => Unload();
private void MvxWindow_Loaded(object sender, RoutedEventArgs e)
{
ViewModel?.ViewAppearing();
ViewModel?.ViewAppeared();
}
private void Unload()
{
if (!_unloaded)
{
ViewModel?.ViewDisappearing();
ViewModel?.ViewDisappeared();
ViewModel?.ViewDestroy();
_unloaded = true;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~DevexpressMvxWindow()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Unloaded -= MvxWindow_Unloaded;
Loaded -= MvxWindow_Loaded;
Closed -= MvxWindow_Closed;
}
}
}
然后在 XAML 中你可以这样使用它:
<customView:DevexpressMvxWindow
xmlns:views="clr-namespace:MvvmCross.Platforms.Wpf.Views;assembly=MvvmCross.Platforms.Wpf"
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:customView="clr-namespace:MvxSample.Wpf"
x:Class="MvxSample.Wpf.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="800" Width="1000">
</customView:DevexpressMvxWindow>