У меня есть приложение WPF.
С левой стороны находится панель стека, полная кнопок.
Справа находится пустая док-панель.
Когда пользователь нажимает кнопку , он загружает соответствующий UserControl (просмотр) в панель ввода:
private void btnGeneralClick(object sender, System.Windows.RoutedEventArgs e)
{
PanelMainContent.Children.Clear();
Button button = (Button)e.OriginalSource;
Type type = this.GetType();
Assembly assembly = type.Assembly;
IBaseView userControl = UserControls[button.Tag.ToString()] as IBaseView;
userControl.SetDataContext();
PanelMainContent.Children.Add(userControl as UserControl);
}
Этот шаблон хорошо работает , поскольку каждый UserControl является представлением, которое имеет класс ViewModel, который передает ему информацию, полученную из модели, поэтому пользователь может переходить от страницы к странице, и каждая страница может выполнять изолированные функции, такие как редактирование всех клиентов, сохранение в базе данных и т. д.
Проблема:
Однако теперь на одной из этих страниц я хочу иметь ListBox со списком клиентов, и у каждого клиента есть кнопка «Изменить», и когда эта кнопка редактирования нажата, я хочу заполнить DockPanel. с помощью EditSingleCustomer UserControl и передайте его клиенту, который необходимо отредактировать.
Я могу загрузить пользовательский контроль EditCustomer, но как мне передать его клиенту для редактирования и настроить его DataContext для редактирования этого клиента ?
- Я не могу передать его в конструкторе, так как все пользовательские элементы управления уже созданы и существуют в словаре в MainWindow.xaml.cs.
- поэтому я создал метод PrepareUserControl для каждого UserControl и передал ему Customer, который может отображать его с текстовым полем из кода с x: Name = "...", но это не главное, мне нужно DataBind ItemsControl к ObservableCollection, чтобы воспользоваться преимуществами функциональности привязки данных WPF.
- , поэтому я попытался привязать ListBox ItemSource в представлении к его коду:
<UserControl.Resources>
<local:ManageSingleCustomer x:Key="CustomersDataProvider"/>
</UserControl.Resources>
<DockPanel>
<ListBox ItemsSource="{Binding Path=CurrentCustomersBeingEdited, Source={StaticResource CustomersDataProvider}}"
ItemTemplate="{DynamicResource allCustomersDataTemplate}"
Style="{DynamicResource allCustomersListBox}">
</ListBox>
</DockPanel>
, который получает ошибку переполнения стека, вызванную бесконечным циклом в IntializeComponent () в этом представлении. Так что я думаю, что я поступаю об этом неправильно, должна быть какая-то более простая парадигма, чтобы просто передавать команды от одного UserControl к другому UserControl в WPF (и до того, как кто-то скажет «использовать командование WPF» Я уже использую командование на моем UserControl, которое позволяет пользователю редактировать всех клиентов, что работает нормально, но я должен обрабатывать это в моем коде позади моего представления (а не в моей viewmodel), так как мне нужен контекст родительского окна для иметь возможность загрузить другой пользовательский элемент управления после его сохранения:
<Button Style="{StaticResource formButton}"
Content="Save"
Command="local:Commands.SaveCustomer"
CommandParameter="{Binding}"/>
private void OnSave(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
{
Customer customer = e.Parameter as Customer;
Customer.Save(customer);
MainWindow parentShell = Window.GetWindow(this) as MainWindow;
Button btnCustomers = parentShell.FindName("btnCustomers") as Button;
btnCustomers.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
}
Так как в WPF я могу просто загрузить UserControl в DockPanel, внутри этого UserControl есть кнопка с командой, которая загружает другой UserControl и отправляет этому UserControl конкретный объект, с которым он может связываться его элементы управления?
Я могу себе представить, что на данный момент я просто недостаточно знаю о командах WPF, если кто-то может указать мне правильное направление отсюда, это было бы замечательно, или если вы думаете, что эта «загрузка UserControls в шаблон DockPanel чужда» в WPF, и его следует избегать и заменять другим способом структурирования приложений », что также будет полезной новостью. Вы можете загрузить текущее состояние моего приложения здесь , чтобы получить представление о его структуре. Спасибо.