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

ncecgwcz  于 2023-11-21  发布在  其他
关注(0)|答案(2)|浏览(140)

我在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中错误的地方创建了弹出控件。但是我不能弄清楚。


的数据

xjreopfe

xjreopfe1#

您错误地实现了数据上下文(ViewModel)和命令。
下面是一个基于基类的例子:BaseInpc and 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>


的数据

mm9b1k5b

mm9b1k5b2#

像这样从ListView控件中提取弹出控件,并像这样在ListView控件中添加selection changed事件:

<Grid x:Name="SubGrid" Grid.Column="1">
<Grid.RowDefinitions>
    <RowDefinition Height="20"/>
    <RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView SelectionChanged="listView_SelectionChanged" ... />
 <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>

字符串
现在,在这种情况下,你需要打开弹出窗口控制,只有选定的项目,而不是所有(因为这是这是你的要求):

private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (listView.SelectedItem != null)
    {
        itemInfosPopup.IsOpen = true;
    }
    else
    {
        itemInfosPopup.IsOpen = false;
    }
   
}


就是这样
重要提示:这只打开一个弹出窗口,现在你需要处理关闭和打开另一个选择改变(当你点击并选择其他项目)。你的任务是打开一个单一的一个选定的项目:)和小心,因为弹出控件处理可能是棘手的。

相关问题