Извините за заголовок, но это было лучшее, что я мог придумать.Позвольте мне объяснить мою проблему: у меня есть приложение WPF, которое имеет меню, похожее на ваше стандартное верхнее меню, которое занимает всего 5% экрана.Нажмите пункт меню, и вид ниже изменится.Элемент управления меню самодельный по причинам: динамические изменения элементов меню, странный пользовательский интерфейс, который не соответствует существующим элементам управления и т. Д.
Часть представления изменения меню выполняется с помощью ContentControl, который привязывается к элементу управления.Свойство CurrentMenuView.При щелчке по пункту меню происходит следующее (псевдокод):
private async void Button_Pressed(...)
{
await MakeSomeVisualMenuChanges();
CurrentMenuView = new CarsView();
await MakeSomOtherStuff();
}
Проблема заключается в том, что некоторым представлениям требуется некоторое время для загрузки, что также замедляет выполнение других шагов.Я хотел бы начать загрузку "CarsView", но в то же время (не после) продолжить другие изменения.Таким образом, пользователь может видеть, как что-то происходит.
Я могу решить эту проблему с помощью Task.Run (), но это кажется неправильным, поскольку он помещает вещи в другой контекст.
Что является правильным / лучшеспособ справиться с этим?
РЕДАКТИРОВАТЬ:
Спасибо за все ответы, как я ожидал, это не легко объяснить.Позвольте мне попробовать простой пример:
MainWindows.xaml:
<Window x:Class="WpfApp32.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="300" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Width="50" Content="Click" Click="Button_Click" />
<ContentControl Grid.Row="1" Width="200" Height="200" Content="{Binding PageContent, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<TextBlock Grid.Row="2" Text="Bottom" Width="300" x:Name="BottomText" />
</Grid>
</Window>
Код сзади:
using System.Windows;
using System.ComponentModel;
namespace WpfApp32
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
BottomText.Text = "AndNowforSomethingCompletelyDifferent";
PageContent = new UserControl1();
}
private object pageContent;
public object PageContent
{
get => pageContent;
set
{
pageContent = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PageContent)));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
UserControl1.xaml:
<UserControl x:Class="WpfApp32.UserControl1"
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"
mc:Ignorable="d"
Loaded="UserControl_Loaded"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock x:Name="CtrlTextBlock" Width="100"/>
</Grid>
</UserControl>
UserControl1.cs:
using System.Windows;
using System.Windows.Controls;
namespace WpfApp32
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void Init()
{
System.Threading.Thread.Sleep(2000);
CtrlTextBlock.Text = "Loaded";
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Init();
}
}
}
Так что это вырезано из асинхронного и т. Д. И просто показывает проблему.Когда кнопка нажата, UserControl1 загружается, но загрузка занимает 2 секунды.До этого текст в элементе «BottomText» остается не заданным.
Как я уже говорил, я могу решить эту проблему, выполнив что-то вроде этого при нажатии кнопки:
private void Button_Click(object sender, RoutedEventArgs e)
{
BottomText.Text = "AndNowforSomethingCompletelyDifferent";
System.Threading.Tasks.Task.Run(() => Application.Current.Dispatcher.Invoke(() => PageContent = new UserControl1()));
}
Но не уверен, что это путь.Итак, основная проблема здесь в том, что ContentControl привязан к свойству, и установка этого свойства может занять некоторое время.Во время загрузки я не хочу, чтобы выполнение в MainWindow было остановлено (я хочу, чтобы элемент BottomText немедленно отображал «AndNowforSomethingCompletelyDifferent»).