如何复制整个网格并将其复制到 WPF 中的其他列表框
How to duplicate a whole grid and copy it to other Listbox in WPF
我的 window 中有两个 ListBox
。我将左侧 Listbox
放置到多个小图像,这些图像在 ImageList
的每个网格中动态填充。
当我从左侧单击图像时,我在右侧放置了空白 Listbox
以显示一张展开的图像。
我已经在 Grid
中列出了图片并放置了点击事件,但我不知道下一步该做什么。
这就是我想要做的。
这是我的代码。
xaml.cs
<ListBox Name="ImageList" ItemsSource="{Binding ImageList}" Grid.Column="0" Height="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding ElementName=ImageList, Path=ActualWidth}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel Orientation="Horizontal">
<!--image and dimensions-->
<Grid Width="300" Height="360" Background="Transparent" MouseDown="Grid_Click">
<StackPanel>
<TextBlock ></TextBlock>
<Image Source="{Binding Path}"/>
<TextBlock >
<TextBlock.Text>
<MultiBinding >
<Binding Path=/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBlock >
<TextBlock.Text>
<MultiBinding StringFormat="">
<Binding Path=/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Grid>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Grid.Column="1"></ListBox>
代码隐藏
private void Grid_Click(object sender, MouseButtonEventArgs e)
{
// What should I do here?
}
要以 WPF 方式执行此操作,您不必使用点击事件。
在 ListView 中尝试 SelectedItems。
Xaml代码
<Window x:Class="sof3.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:sof3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" ItemsSource="{Binding ImagePathList}" SelectedItem="{Binding SelectedImagePath, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding ImagePath}"/>
<Image Source="{Binding ImagePath}" Stretch="Fill" Width="200" Height="200"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Image Grid.Column="1" Source="{Binding SelectedImagePath.ImagePath}" Stretch="Fill" Width="200" Height="200"/>
</Grid>
</Window>
MainViewModel 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace sof3
{
class MainViewModel : INotifyPropertyChanged
{
public ObservableCollection<Image> ImagePathList
{
get
{
if (_imagePathList == null) _imagePathList = new ObservableCollection<Image>();
return _imagePathList;
}
set
{
_imagePathList = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ImagePathList)));
}
}
private ObservableCollection<Image> _imagePathList;
public Image SelectedImagePath
{
get
{
return _selectImagePath;
}
set
{
_selectImagePath = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedImagePath)));
}
}
public Image _selectImagePath;
public event PropertyChangedEventHandler PropertyChanged;
}
public class Image : INotifyPropertyChanged
{
public string ImagePath {
get
{
return _imagePath;
}
set
{
_imagePath = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ImagePath)));
}
}
private string _imagePath;
public event PropertyChangedEventHandler PropertyChanged;
}
}
主要代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace sof3
{
/// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainWindow : Window
{
private MainViewModel _instance;
public MainWindow()
{
InitializeComponent();
_instance = new MainViewModel();
this.DataContext = _instance;
_instance.ImagePathList.Add(new Image() { ImagePath = @"C:\Users\dskim\source\repos\sof3\sof3\bin\Debug.bmp" });
_instance.ImagePathList.Add(new Image() { ImagePath = @"C:\Users\dskim\source\repos\sof3\sof3\bin\Debug.bmp" });
_instance.ImagePathList.Add(new Image() { ImagePath = @"C:\Users\dskim\source\repos\sof3\sof3\bin\Debug.bmp" });
_instance.ImagePathList.Add(new Image() { ImagePath = @"C:\Users\dskim\source\repos\sof3\sof3\bin\Debug.bmp" });
}
}
}
//Change Image Path
您的代码示例似乎还在制作中,因此我将只关注您的问题。如果您只想在右侧绑定一张图像,请使用简单的 Image
控件,而不是 ListBox
。然后就可以直接在XAML中绑定选中的item了
<Grid>
<!-- ...grid row and column definitions -->
<ListBox Name="ImageList" ItemsSource="{Binding ImageList}" Grid.Column="0" Height="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<!-- ...your item data template. -->
</ListBox.ItemTemplate>
</ListBox>
<Image Grid.Column="1" Source="{Binding SelectedItem.Path, ElementName=ImageList}"/>
</Grid>
我跳过了大部分相同的代码。基本上,您只需要复制替换第二个 ListBox
的 <Image ...>
行。它所做的是通过其名称引用第一个 ListBox
并绑定所选项目的 Path
。我还省略了 WrapPanel
上的 Width
绑定,因为它是多余的。
我的 window 中有两个 ListBox
。我将左侧 Listbox
放置到多个小图像,这些图像在 ImageList
的每个网格中动态填充。
当我从左侧单击图像时,我在右侧放置了空白 Listbox
以显示一张展开的图像。
我已经在 Grid
中列出了图片并放置了点击事件,但我不知道下一步该做什么。
这就是我想要做的。
这是我的代码。
xaml.cs
<ListBox Name="ImageList" ItemsSource="{Binding ImageList}" Grid.Column="0" Height="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Width="{Binding ElementName=ImageList, Path=ActualWidth}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel Orientation="Horizontal">
<!--image and dimensions-->
<Grid Width="300" Height="360" Background="Transparent" MouseDown="Grid_Click">
<StackPanel>
<TextBlock ></TextBlock>
<Image Source="{Binding Path}"/>
<TextBlock >
<TextBlock.Text>
<MultiBinding >
<Binding Path=/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBlock >
<TextBlock.Text>
<MultiBinding StringFormat="">
<Binding Path=/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Grid>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Grid.Column="1"></ListBox>
代码隐藏
private void Grid_Click(object sender, MouseButtonEventArgs e)
{
// What should I do here?
}
要以 WPF 方式执行此操作,您不必使用点击事件。
在 ListView 中尝试 SelectedItems。
Xaml代码
<Window x:Class="sof3.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:sof3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" ItemsSource="{Binding ImagePathList}" SelectedItem="{Binding SelectedImagePath, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding ImagePath}"/>
<Image Source="{Binding ImagePath}" Stretch="Fill" Width="200" Height="200"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Image Grid.Column="1" Source="{Binding SelectedImagePath.ImagePath}" Stretch="Fill" Width="200" Height="200"/>
</Grid>
</Window>
MainViewModel 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace sof3
{
class MainViewModel : INotifyPropertyChanged
{
public ObservableCollection<Image> ImagePathList
{
get
{
if (_imagePathList == null) _imagePathList = new ObservableCollection<Image>();
return _imagePathList;
}
set
{
_imagePathList = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ImagePathList)));
}
}
private ObservableCollection<Image> _imagePathList;
public Image SelectedImagePath
{
get
{
return _selectImagePath;
}
set
{
_selectImagePath = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedImagePath)));
}
}
public Image _selectImagePath;
public event PropertyChangedEventHandler PropertyChanged;
}
public class Image : INotifyPropertyChanged
{
public string ImagePath {
get
{
return _imagePath;
}
set
{
_imagePath = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ImagePath)));
}
}
private string _imagePath;
public event PropertyChangedEventHandler PropertyChanged;
}
}
主要代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace sof3
{
/// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainWindow : Window
{
private MainViewModel _instance;
public MainWindow()
{
InitializeComponent();
_instance = new MainViewModel();
this.DataContext = _instance;
_instance.ImagePathList.Add(new Image() { ImagePath = @"C:\Users\dskim\source\repos\sof3\sof3\bin\Debug.bmp" });
_instance.ImagePathList.Add(new Image() { ImagePath = @"C:\Users\dskim\source\repos\sof3\sof3\bin\Debug.bmp" });
_instance.ImagePathList.Add(new Image() { ImagePath = @"C:\Users\dskim\source\repos\sof3\sof3\bin\Debug.bmp" });
_instance.ImagePathList.Add(new Image() { ImagePath = @"C:\Users\dskim\source\repos\sof3\sof3\bin\Debug.bmp" });
}
}
}
//Change Image Path
您的代码示例似乎还在制作中,因此我将只关注您的问题。如果您只想在右侧绑定一张图像,请使用简单的 Image
控件,而不是 ListBox
。然后就可以直接在XAML中绑定选中的item了
<Grid>
<!-- ...grid row and column definitions -->
<ListBox Name="ImageList" ItemsSource="{Binding ImageList}" Grid.Column="0" Height="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<!-- ...your item data template. -->
</ListBox.ItemTemplate>
</ListBox>
<Image Grid.Column="1" Source="{Binding SelectedItem.Path, ElementName=ImageList}"/>
</Grid>
我跳过了大部分相同的代码。基本上,您只需要复制替换第二个 ListBox
的 <Image ...>
行。它所做的是通过其名称引用第一个 ListBox
并绑定所选项目的 Path
。我还省略了 WrapPanel
上的 Width
绑定,因为它是多余的。