Я новичок в программировании C# WPF и работаю над WPF-приложением, которое должно включать устаревший компонент ActiveX
. Я знаю, что ActiveX
мертв, но, к сожалению, мне приходится использовать его в этом случае. Я использую MVVM Light
с IFrameNavigationService
, как показано в этом посте .
Кроме того, я использовал этот пример , чтобы привязать компонент ActiveX
в представлении к следуйте рекомендациям MVVM
, что, на мой взгляд, не лучший способ.
При каждой навигации мне приходится ждать, пока страница загрузится, чтобы подключиться к компоненту ActiveX
(VideoService
). Операция подключения занимает около 5 секунд. Таким образом, пользователю приходится долго ждать, чтобы использовать страницу, что, очевидно, плохо.
Теперь у меня есть два вопроса:
Как бы вы включаете компонент ActiveX
в шаблон MVVM
? К сожалению, мне нужен VideoService
для потоковой передачи видео, заданного VideoService
в представлении, и мне нужно VideoService
для запроса данных видео в ViewModel.
Как Могу ли я использовать компонент ActiveX
на каждой странице, не монтируя его при каждом изменении страницы?
Просмотр / Главный Windows .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");
});
}
}
}
Просмотр / Страницы / Главная .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");
});
}
}
}