弹出窗口在列表视图WPF中多次显示

问题描述 投票:0回答:1

我正在 WPF 中开发一个项目。我有列表视图控件,在该列表视图中我有文本块和按钮作为模板控件。

我希望当用户单击按钮时弹出窗口打开并显示所选项目的信息。但是,当单击按钮时,弹出窗口会多次显示(项目计数)。

这些是 XAML 代码。

<Window x:Class="TestingPopupShow.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:vm="clr-namespace:TestingPopupShow.ViewModel"
        xmlns:local="clr-namespace:TestingPopupShow"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="400">

    <Window.Resources>
        <ResourceDictionary>
            <vm:ItemInfosPopupVM x:Key="vm"/>
        </ResourceDictionary>
    </Window.Resources>
    
   
        <Grid   x:Name="SubGrid" Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="20"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <ListView  x:Name="listView" 
              Grid.Row="1"
              Margin="0 5 0 0">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Border x:Name="debugPanel"  CornerRadius="3" BorderBrush="Black" BorderThickness="0.5"  Grid.Column="0" Grid.RowSpan="2">
                            <Grid DataContext="{StaticResource vm}"  x:Name="listViewGrid" Margin="1"
                      HorizontalAlignment="Center"
                      Background="#F2F2F2">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="80"/>
                                    <ColumnDefinition Width="120"/>
                                    <ColumnDefinition Width="25"/>
                                </Grid.ColumnDefinitions>

                                <Grid.RowDefinitions>
                                    <RowDefinition Height="80"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>

                                <StackPanel Grid.Column="0">
                                    <TextBlock Text="W01"
                                               FontSize="12"
                                               Margin="5"
                                               FontFamily="Tohama"/>
                                    <TextBlock Text="1 pcs"
                                               FontSize="12"
                                               Margin="5"
                                               FontFamily="Tohama"/>


                                    <TextBlock Text="1200 X 1600"
                                               FontSize="12"
                                               Margin="5"
                                               FontFamily="Tohama"/>
                                </StackPanel >

                                <DockPanel x:Name="imageDockPanel" Grid.Column="1">

                                </DockPanel >
                                <Button Grid.Column="2"
                                            BorderThickness="0"
                                                Command="{Binding showPopupCommand}"
                                            x:Name="buttonOpen" 
                                            Content=">"
                                            HorizontalAlignment="Stretch"/>
                                <Popup x:Name="itemInfosPopup" 
                                                   
                                              StaysOpen="False"
                                               Placement="Mouse"
                                               IsOpen="{Binding PopupVis, UpdateSourceTrigger=PropertyChanged}"
                                               AllowsTransparency="True">
                                    <Border BorderBrush="Black" BorderThickness="2">
                                        <StackPanel Background="White" Width="200" Height="300">

                                        </StackPanel>
                                    </Border>
                                </Popup>
                            </Grid>
                        </Border>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
</Window>

这是 ViewModel 类

public class ItemInfosPopupVM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool popupVis;
    public bool PopupVis
    {
        get { return popupVis; }
        set
        {
            popupVis = value;
            OnPropertyChanged("PopupVis");
        }
    }
    
    public ShowPopupCommand showPopupCommand { get; set; }
    public ItemInfosPopupVM()
    {
        PopupVis = false;
        showPopupCommand = new ShowPopupCommand(this);
    }
       
    public void ShowPopup()
    {
        if (PopupVis)
        {
            PopupVis = false;
        }
        else
        {
            PopupVis = true;
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

这些是命令类:

public class ShowPopupCommand : ICommand
{
    public ItemInfosPopupVM ViewModel { get; set; }
    public event EventHandler CanExecuteChanged;
    public ShowPopupCommand(ItemInfosPopupVM vm)
    {
        ViewModel = vm;
    }

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

    public void Execute(object parameter)
    {
        ViewModel.ShowPopup();
    }
}

这些是在主窗口视图中测试的临时代码

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Temporary codes. Testing listview.
        for (int i = 0; i < 5; i++)
        {
            listView.Items.Add("Item " + i.ToString());
        }
    }
}

我认为我在 XAML 中的错误位置创建了弹出控件。但我无法弄清楚。

c# wpf templates listview popup
1个回答
0
投票

您错误地实现了数据上下文 (ViewModel) 和命令。
以下是基于此处的基类的示例:BaseInpc 和 RelayCommand

    public class ItemInfosPopupVM : BaseInpc
    {
        private bool popupVis;
        private string title = string.Empty;

        public bool PopupVis { get => popupVis; set => Set(ref popupVis, value); }

        public string Title { get => title; set => Set(ref title, value ?? string.Empty); }
    }
    public class ItemsVM
    {
        public ObservableCollection<ItemInfosPopupVM> ItemInfos { get; } = new();

        public ItemsVM()
        {
            // Temporary codes. Testing listview.
            for (int i = 0; i < 5; i++)
            {
                ItemInfos.Add(new ItemInfosPopupVM { Title = "Item " + i.ToString() });
            }

            InvertPopupVis = new RelayCommand<ItemInfosPopupVM>
            (
                item => item.PopupVis = !item.PopupVis
            );
        }

        public RelayCommand<ItemInfosPopupVM> InvertPopupVis { get; }
    }
<Window x:Class="TestingPopupShow.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:vm="clr-namespace:TestingPopupShow.ViewModel"
        xmlns:local="clr-namespace:TestingPopupShow"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="400"
        DataContext="{DynamicResource vm}">
    <Window.Resources>
        <vm:ItemsVM x:Key="vm"/>
    </Window.Resources>


    <Grid   x:Name="SubGrid" Grid.Column="1">
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ListBox ItemsSource="{Binding ItemInfos}"
              Grid.Row="1"
              Margin="0 5 0 0">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="{x:Type vm:ItemInfosPopupVM}">
                    <Border CornerRadius="3" BorderBrush="Black" BorderThickness="0.5"  Grid.Column="0" Grid.RowSpan="2">
                        <Grid Margin="1"
                              HorizontalAlignment="Center"
                              Background="#F2F2F2">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="80"/>
                                <ColumnDefinition Width="120"/>
                                <ColumnDefinition Width="25"/>
                            </Grid.ColumnDefinitions>

                            <Grid.RowDefinitions>
                                <RowDefinition Height="80"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>

                            <StackPanel Grid.Column="0">
                                <TextBlock Text="{Binding Title, StringFormat='{}{0} - W01'}"
                                           FontSize="12"
                                           Margin="5"
                                           FontFamily="Tohama"/>
                                <TextBlock Text="1 pcs"
                                           FontSize="12"
                                           Margin="5"
                                           FontFamily="Tohama"/>


                                <TextBlock Text="1200 X 1600"
                                           FontSize="12"
                                           Margin="5"
                                           FontFamily="Tohama"/>
                            </StackPanel >

                            <DockPanel x:Name="imageDockPanel" Grid.Column="1">

                            </DockPanel >
                            <Button Grid.Column="2"
                                    BorderThickness="0"
                                    Command="{Binding InvertPopupVis, Source={StaticResource vm}}"
                                    CommandParameter="{Binding}"
                                    Content=">"
                                    HorizontalAlignment="Stretch"/>
                            <Popup StaysOpen="False"
                                   Placement="Mouse"
                                   IsOpen="{Binding PopupVis, UpdateSourceTrigger=PropertyChanged}"
                                   AllowsTransparency="True">
                                <Border BorderBrush="Black" BorderThickness="2">
                                    <StackPanel Background="White" Width="200" Height="300">

                                    </StackPanel>
                                </Border>
                            </Popup>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

© www.soinside.com 2019 - 2024. All rights reserved.