Как выполнить обратный вызов кода в пользовательском элементе управления WPF

#c# #wpf

#c# #wpf

Вопрос:

Я использую wpf. Я создал пользовательский элемент управления. В этом элементе управления у меня есть несколько кнопок. Я могу привязать команды кнопок к viewmodel. Однако в этом приложении мне нужно выполнить обратный вызов файла code back, а не viewmdoel. Как я могу это сделать?

Вот пример моего пользовательского элемента управления:

 <Grid>
    <StackPanel Orientation="Horizontal" Grid.Row="3">
        <Button Content="Button A" Command="{Binding SwitchToABCCommand}">
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding CurRegion}" Value="ABC">
                            <Setter Property="Foreground" Value="Red" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
        <Button Content="Button B" Command="{Binding SwitchToEFGCommand}">
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding CurRegion}" Value="DEF">
                            <Setter Property="Foreground" Value="Red" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </StackPanel>
</Grid>
 

Затем у меня есть другое окно, использующее этот пользовательский элемент управления.

MainWindowViewModel.cs

 public ICommand SwitchToABCCommand { get; }
public ICommand SwitchToDEFCommand { get; }
public MainWindowViewModel()
{
    SwitchToABCCommand = new DelegateCommand(HandleSwitchToABCCommand);
    SwitchToEFGCommand = new DelegateCommand(HandleSwitchToEFGCommand);
}
private void HandleSwitchToABCCommand()
{

}
private void HandleSwitchToDEFCommand()
{

}
 

И я хочу выполнить обратный вызов MainWindow.xaml.cs

 private void SwitchToABC(object sender, RoutedEventArgs e)
{
}
private void SwitchToDEF(object sender, RoutedEventArgs e)
{
}
 

Я пытался это сделать:

 <Button Content="Button A" Click="SwitchToABC">
 

Но это может быть только обратный MyCustomControl.xaml.cs вызов . Как я могу перезвонить в MainWindow.xaml.cs?

Спасибо

Комментарии:

1. Итак, вы предполагаете, что элемент управления всегда используется в контексте модели представления, которая имеет SwitchToABCCommand или главное окно?

2. Есть какая-то конкретная причина, по которой вам нужно вызывать code behind? Конечно, основная модель представления будет обладать такой функциональностью. И если вы ищете связь между моделями представлений, посмотрите на шаблон обмена сообщениями.

3. Если я правильно прочитал ваше требование, вы хотите выполнить обратный вызов в коде страницы из элемента управления — и вам не следует делать это так, как вы думаете. Элемент управления не должен иметь никаких сведений о более широкой среде, в которой он размещен. Однако вы можете объявить обработчик событий (делегат) и вызвать этот обработчик / делегат, если он установлен.

Ответ №1:

Обработчик событий должен быть определен в том же классе, что и разметка XAML. Если вы определяете SwitchToABC в MyCustomControl.xaml.cs , вы можете вызвать обработчик событий MainWindow оттуда, хотя:

 private void SwitchToABC(object sender, RoutedEventArgs e)
{
    MainWindow parentWindow = Window.GetWindow(this) as MainWindow;
    if (parentWindow != null)
    {
        parentWindow.SomeHandler(sender, e);
    }
}
 

Обратите внимание, что это создает сильную связь между элементом управления и окном.

Привязка к SwitchToABCCommand команде в элементе управления XAML также создает косвенную связь с моделью представления. Лучшим способом было бы добавить свойство command к элементу управления и привязать его к свойству команды view model, например:

 <MyCustomControl YourCommand="{Binding SwitchToABCCommand }"  />
 

Комментарии:

1. Большое вам спасибо. Для метода свойств я сначала буду искать информацию. Я не уверен, как привязать YourCommand к кнопке в моем StackPanel , поскольку у меня несколько кнопок.