Вложенный элемент управления WPF User Control - переключение Usercontrol из Usercontrol - PullRequest
0 голосов
/ 17 марта 2020

В настоящее время я разрабатываю приложение с WPF в Visual Studio в качестве внешнего интерфейса для базы данных MySQL, которую затем предполагается использовать в школе для организации оборудования и т. Д. c. немного проще Я совершенно новичок в C# и WPF и поэтому столкнулся с проблемой, которую не смог решить в последние часы. Пользовательский интерфейс состоит из окна с Navbar et c. и большой Frame / Grid, который используется для отображения текущего UserControl.

Нажатие на кнопку в панели навигации моего главного окна вызывает событие, которое затем переключает UserControl без каких-либо проблем просто с этими строками:

ContentFrame.Children.Clear();  //ContentFrame is a simple Grid which I am using ot display the UserControls
ContentFrame.Children.Add(new UserControlDashboard());  //UserControlDashboard is the Class of one of my UserControls

Я не знаю, действительно ли это лучший способ реализовать это (поскольку он всегда перезагружает UserControl), но, по крайней мере, он прост и работает.

Проблема в том, что я Может переключать пользовательские элементы управления только через класс Mainwindow. Но я хочу иметь возможность переключать UserControl из одного из UserControls. (Например, один из моих UserControls показывает dataGrid со всеми данными из одной из моих таблиц БД. Двойным щелчком по одной из этих строк я хочу иметь возможность переключить текущий UserControl с этой таблицей на другую.)

Но я не могу понять, как я могу это сделать. Я провел некоторые исследования, но нашел только решения, которые состояли из десятков разных классов с множеством разных Eventhandlers и др. c. и, к сожалению, я не мог понять, как работает эта реализация. И это также было ограничено 2 UserControls.

Можно ли как-нибудь реализовать это за разумное количество времени? Я читал, что это можно сделать с помощью перенаправленных событий? Поскольку я новичок в C#, я совершенно новичок в событиях, диспетчеры и др. c. и, следовательно, с трудом справляются со всеми этими событиями. : D

Спасибо :)

1 Ответ

1 голос
/ 18 марта 2020

Простым решением будет использование привязки данных:

MainWindow.xaml

<Window>
  <StackPanel>
    <SwitchingControl x:Name="BindingSourceControl" />
    <ContentControl x:Name="ContentFrame" 
                    Content="{Binding ElementName=BindingSourceControl, Path=SelectedControl}" />
  </StackPanel>
</Window>

SwitchingControl.xaml.cs

partial class SwitchingControl : UserControl
{
  public static readonly DependencyProperty SelectedControlProperty = DependencyProperty.Register(
    "SelectedControl",
    typeof(Control),
    typeof(SwitchingControl),
    new PropertyMetadata(default(Control)));

  public Control SelectedControl
  {
    get => (Control) GetValue(SwitchingControl.SelectedControlProperty);
    set => SetValue(SwitchingControl.SelectedControlProperty, value);
  }

  // Dictionary to store reusable controls
  private Dictionary<string, Control> ControlMap { get; set; }

  public SwitchingControl()
  {
    this.ControlMap = new Dictionary<string, Control>() 
    { 
      { nameof(UserControlDashboard), new UserControlDashboard()) }
    };
  }

  // TODO::Invoke when a DataGrid row was double clicked
  private void OnNewControlSelected(string selectedControlKey)
  {
    if (this.ControlMap.TryGetValue(selectedControlKey, out Control selectedControl)
    {
      this.SelectedControl = selectedControl;
    }
  }
}

Более продвинутое решение будет включать DataTemplate и различные модели представлений или моделей данных, для которых указанный тип c будет сопоставлен с указанным c элементом управления. Затем элемент управления отображается, когда модель добавляется, например, к ContentPresenter, что автоматически применяет правильный DataTemplate для визуализации данных модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...