Я очень новичок в WPF, но с большим опытом. NET и C#. Я пытаюсь создать (как я думаю, было бы) довольно простое приложение рабочего стола администратора CRUD для веб-сайта, который я планирую создать.
Кажется, что WPF намного сложнее, чем я ожидал, и после многих Поиск в Google Я в основном понял, что каждый использует шаблон MVVM - отлично. Теперь, с моим существующим опытом. NET, я знаю, что определенно хочу использовать внедрение зависимостей. Я обнаружил, что, похоже, все сделано в ViewModel в WPF, включая все сервисы и все - опять хорошо.
Теперь по моей проблеме. Я установил базовый элемент управления c tab и привязываю значения табуляции к перечислению, используя Enum.GetValues()
. Я хочу, чтобы вид менялся при выборе вкладки, и вид будет зависеть от того, какая вкладка выбрана. Проблема в том, что я не могу показать вид - он просто показывает пустой экран. Представление - это пользовательский элемент управления UserControl, который я создал и определил как ресурс, и он содержит сетку, набор кнопок и прочее. Я пропустил это снизу, поскольку это не выглядит актуальным.
My MainWindow.xaml довольно просто и выглядит так:
<Window x:Class="Stc.Admin.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"
xmlns:viewmodels="clr-namespace:Stc.Admin.ViewModels"
xmlns:views="clr-namespace:Stc.Admin.Views"
xmlns:local="clr-namespace:Stc.Admin"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TabControl ItemsSource="{Binding Tabs}" SelectedItem="{Binding CurrentTab}">
<TabControl.Resources>
<DataTemplate DataType="{x:Type viewmodels:GamesViewModel}">
<views:Games />
</DataTemplate>
</TabControl.Resources>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentControl Content="{Binding DataContext.CurrentViewModel, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}}" />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</Window>
Вот мой MainViewModel.cs :
public class MainViewModel
{
private readonly IViewModelFactory<GamesViewModel> _gamesViewModelFactory;
private ViewType _currentTab;
public ViewType CurrentTab
{
get
{
return _currentTab;
}
set
{
_currentTab = value;
ChangeView(_currentTab);
}
}
public ObservableCollection<ViewType> Tabs { get; }
public ViewModelBase CurrentViewModel { get; set; }
public MainViewModel(IViewModelFactory<GamesViewModel> gamesViewModelFactory)
{
_gamesViewModelFactory = gamesViewModelFactory;
Tabs = new ObservableCollection<ViewType>(Enum.GetValues(typeof(ViewType)).Cast<ViewType>().ToArray());
}
private void ChangeView(ViewType viewType)
{
switch (viewType)
{
case ViewType.Games:
CurrentViewModel = _gamesViewModelFactory.CreateViewModel();
break;
case ViewType.Listings:
break;
case ViewType.Users:
break;
case ViewType.Languages:
break;
case ViewType.Currencies:
break;
default:
break;
}
}
}
public enum ViewType
{
Games,
Listings,
Users,
Languages,
Currencies
}
GamesViewModel
имеет служебные зависимости, поэтому его необходимо создать с использованием фабрики.
И мои настройки DI в App .xaml.cs :
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
IServiceProvider serviceProvider = this.createServiceProvider();
Window window = new MainWindow();
window.DataContext = serviceProvider.GetRequiredService<MainViewModel>();
window.Show();
base.OnStartup(e);
}
private IServiceProvider createServiceProvider()
{
IServiceCollection services = new ServiceCollection();
services.AddDbContext<StcContext>(options =>
options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Stc;Integrated Security=True"));
services.AddSingleton<ICrudService<Game>, CrudService<Game>>();
services.AddSingleton<IViewModelFactory<GamesViewModel>, GamesViewModelFactory>();
services.AddScoped<MainViewModel>();
return services.BuildServiceProvider();
}
}