问题
I am new to C# WPF programming and working on a WPF-Application that has to include a legacy ActiveX
component. I know ActiveX
is kind of dead but I have to use it in this case unfortunately.
I use MVVM Light
with an IFrameNavigationService
as shown in this post.
Furthermore I used this example to bind the ActiveX
component into the view to follow the guidlines of MVVM
which is probalby not the best way in my opinion.
On each navigation I have to wait until page is loaded to connect with the ActiveX
component (VideoService
). The connecting operation takes about 5 seconds.
So the user has to wait a long time to use the page which is obviously bad.
Now I got two questions:
How would you include an
ActiveX
component into theMVVM
pattern? Unfortunately I need theVideoService
to stream a video given by theVideoService
in the View and I need theVideoService
to request data of the video in the ViewModel.How can I use the
ActiveX
component on every page without (un)mounting it on every page change?
View/MainWindows.xaml
<Window x:Class="View.Desktop.MainWindow"
...
DataContext="{Binding Main, Source={StaticResource Locator}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding WindowLoadedCommand }" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<Frame x:Name="MainFrame" NavigationUIVisibility="Hidden" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</Grid>
</Window>
ViewModel/MainViewModel.cs
{
public class MainViewModel : ViewModelBase
{
private readonly IFrameNavigationService navigationService;
public RelayCommand WindowLoadedCommand { get; private set; }
public MainViewModel(IFrameNavigationService navService)
{
navigationService = navService;
WindowLoadedCommand = new RelayCommand(() =>
{
navigationService.NavigateTo("Home");
});
}
}
}
View/Pages/Home.xaml
<Page x:Class="View.Desktop.Pages.HomePage"
...
DataContext="{Binding HomeViewModel,Source={StaticResource Locator}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding PageLoadedCommand }" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<ContentControl Content="{Binding VideoWindowsFormsHost}" />
<Button Content="Navigate" Command="{Binding NavigateCommand}" />
</Grid>
</Page>
ViewModel/HomeViewModel.cs
{
public class HomeViewModel : ViewModelBase
{
private readonly IFrameNavigationService navigationService;
readonly VideoService video;
public WindowsFormsHost VideoWindowsFormsHost
{
get { return new WindowsFormsHost() { Child = video.v }; }
}
public ICommand PageLoadedCommand { get; private set; }
public ICommand NavigateCommand { get; private set; }
public HomeViewModel(IFrameNavigationService navService)
{
navigationService = navService;
video = new VideoService();
PageLoadedCommand = new RelayCommand(async () =>
{
// Very slow
video.connect();
});
NavigateCommand = new RelayCommand(() =>
{
video.Disconnect();
navigationService.NavigateTo("Settings");
});
}
}
}
View/Pages/Settings.xaml
<Page x:Class="View.Desktop.Pages.SettingsPage"
...
DataContext="{Binding SettingsViewModel,Source={StaticResource Locator}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding PageLoadedCommand }" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<ContentControl Content="{Binding VideoWindowsFormsHost}" />
<Button Content="Navigate" Command="{Binding NavigateCommand}" />
</Grid>
</Page>
ViewModel/SettingsViewModel.cs
{
public class SettingsViewModel : ViewModelBase
{
private readonly IFrameNavigationService navigationService;
readonly VideoService video;
public WindowsFormsHost VideoWindowsFormsHost
{
get { return new WindowsFormsHost() { Child = video.v }; }
}
public ICommand PageLoadedCommand { get; private set; }
public ICommand NavigateCommand { get; private set; }
public SettingsViewModel(IFrameNavigationService navService)
{
navigationService = navService;
video = new VideoService();
PageLoadedCommand = new RelayCommand(async () =>
{
// Very slow
video.connect();
});
NavigateCommand = new RelayCommand(() =>
{
video.Disconnect();
navigationService.NavigateTo("Home");
});
}
}
}
来源:https://stackoverflow.com/questions/62082155/activex-in-wpf-mvvm-light-application