wpf всплывающее окно в пользовательском элементе управления, кнопка не отвечает на события или команды - PullRequest
0 голосов
/ 26 мая 2018

У меня есть следующий пользовательский элемент управления xaml

<UserControl x:Class="tgltestpopup"
         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"  
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Popup  IsOpen="{Binding ElementName=tgl,Path=IsChecked}" StaysOpen="False">
        <Border Background="White">
            <StackPanel>
                <Button Click="showMsgEvent" Content="close"></Button>
                <Button Content="test me" Command="{Binding showMsgCommand,RelativeSource={RelativeSource AncestorType=UserControl}}"></Button>

            </StackPanel>
        </Border>
    </Popup>
    <ToggleButton Content="open popup" x:Name="tgl" HorizontalAlignment="Center" VerticalAlignment="Center"/>

</Grid>

этот пользовательский элемент управления используется в столбце Шаблон таблицы данных.Однако, когда я нажимаю кнопку переключения, отображается всплывающее окно, но кнопки не реагируют на события или команды.Кнопки подсвечиваются, когда мышь проходит над ними, но когда я нажимаю на них, ничего не делаем!. Даже когда я нажимаю кнопку, состояние кнопки не изменяется.Похоже, не узнают кнопку, на которой я нажал.

Есть предложения?

1 Ответ

0 голосов
/ 27 мая 2018

Я получил это с помощью EventTrigger и PreviewMouseDown.По какой-то причине MouseDown не работает, и я думаю, что по этой же причине простая команда тоже не работает.Может быть, фокус меняется, и кнопка на самом деле не нажимается на самом деле.

Но в любом случае, вот что я придумал:

<Window x:Class="TestPopupInDataTemplate.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:local="clr-namespace:TestPopupInDataTemplate"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid AutoGenerateColumns="False"
              ItemsSource="{Binding Source}"
              CanUserAddRows="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="First">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <local:TestUserControl/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

        </DataGrid.Columns>
    </DataGrid>
</Grid>

Чтобы преодолетьэто быстро, я не добавил отдельную модель представления для окна:

public partial class MainWindow : Window
{
    public ObservableCollection<TestViewModel> Source { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        Source = new ObservableCollection<TestViewModel>() { new TestViewModel() { Name = "Test Name11" } };
        this.DataContext = this;
    }
}

Вот UserControl, который установлен на DataTemplate:

<UserControl x:Class="TestPopupInDataTemplate.TestUserControl"
         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" 
         xmlns:local="clr-namespace:TestPopupInDataTemplate"
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="GridName">
    <ToggleButton Content="open popup" x:Name="tgl" HorizontalAlignment="Center" VerticalAlignment="Center"/>

    <Popup  IsOpen="{Binding ElementName=tgl,Path=IsChecked}" 
            StaysOpen="False"                >
        <Border Background="White">
            <StackPanel>
                <!--<Button Click="showMsgEvent" Content="close"></Button>-->
                <Button Content="{Binding Name}"
                        Margin="5"
                        Width="90"
                        Height="30"
                        FontSize="20"                            >
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="PreviewMouseDown">
                            <i:InvokeCommandAction Command="{Binding ShowMsgCommand}" 
                                                   CommandParameter="{Binding}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </Button>

            </StackPanel>
        </Border>
    </Popup>
</Grid>

Его вид модели:

public class TestViewModel
{
    public ICommand ShowMsgCommand { get; set; }

    public string Name { get; set; }
    public TestViewModel()
    {
        ShowMsgCommand = new OpenMsgCommand(this);
    }
    public void OpenMessage()
    {
        Console.WriteLine("test");
    }
}

И команда:

public class OpenMsgCommand : ICommand
{
    private TestViewModel _vm;

    public OpenMsgCommand(TestViewModel vm)
    {
        _vm = vm;
    }
    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _vm.OpenMessage();
    }
}

Вот результат:

enter image description here

Как видите, команда и параметр команды работают должным образом.

Чтобы использовать *, необходимо добавить ссылку на System.Windows.Interactivity.1038 *.

...