c# - WPF ListView - 在未单击所选项目时检测 ListVewItem
问题描述
当用户没有通过单击选择项目但用户点击它时,我试图在 WPF 的 ListView 中获取项目。有没有办法在 WPF ListView 中实现这一点。ListView 数据源由代码隐藏中的动态集合填充。当用户点击它时,我得到一个空对象。
Item selectedItem = (Item)lv_CartItems.SelectedItem;
这就是我的数据模板在列表视图中的样子。
<ListView.ItemTemplate>
<DataTemplate>
<Viewbox>
<Grid Width="230" Height="110" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width=".1*" />
<ColumnDefinition />
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition Width=".5*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border BorderBrush="LightGray" BorderThickness="1"
Grid.Row="0" Grid.Column="0"
Grid.ColumnSpan="6" Grid.RowSpan="3" >
</Border>
<Viewbox Grid.Row="0" >
<Image Name="img_ItemImage"
Source="{Binding Image, Mode=TwoWay }"
Width="20" Height=" 25" />
</Viewbox>
<Viewbox Grid.Column="2" Grid.ColumnSpan="3" VerticalAlignment="Top" >
<TextBlock Name="lbl_ItemName" TextWrapping="Wrap" Width="180" Foreground="Gray"
Text="{Binding Name , Mode=TwoWay }" Tag="{Binding SKU_No,Mode=TwoWay}" >
</TextBlock>
</Viewbox>
<Viewbox Grid.Row="1" Margin="10,0" VerticalAlignment="Top" >
<TextBlock Foreground="Gray" >Qty:</TextBlock>
</Viewbox>
<Viewbox Grid.Row="2" Margin="0,0" VerticalAlignment="Top" >
<StackPanel Orientation="Horizontal" >
<Button Name="btn_Minus" FontWeight="ExtraBold" Padding="0" Width="12"
Resources="{StaticResource cartitembutton}" Click="btn_Minus_Click" >
<Image Source="/Resources\Icons\minus.png" ></Image>
</Button>
<Border BorderThickness="1" Margin="2,0" Width="13" CornerRadius="2" BorderBrush="LightGray" >
<TextBlock Name="lbl_Quantity" FontWeight="Bold" Foreground="Gray"
HorizontalAlignment="Center" VerticalAlignment="Center"
Text="{Binding Quantity , Mode=TwoWay }">
</TextBlock>
</Border>
<Button Name="btn_Increment" FontWeight="ExtraBold" Width="12"
Resources="{StaticResource cartitembutton}"
Padding="0"
Click="btn_Increment_Click">
<Image Source="/Resources\Icons\union_10.png" ></Image>
</Button>
</StackPanel>
</Viewbox>
<Viewbox Grid.Row="1" Grid.Column="2" Margin="5,0"
HorizontalAlignment="Left" Grid.ColumnSpan="3" >
<TextBlock Name="lbl_Price" FontWeight="DemiBold"
Text="{Binding Price , Mode=TwoWay}" ></TextBlock>
</Viewbox>
<Viewbox Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="3"
VerticalAlignment="Top" Margin="0,0" >
<TextBlock Name="lbl_Appearence"
Text="{Binding Appearance , Mode=TwoWay }"
TextWrapping="Wrap" Foreground="Gray" Width="210" >
</TextBlock>
</Viewbox>
<Viewbox Grid.Column="5" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="2,2"
>
<Button Name="btn_DeleteItem"
Click="btn_DeleteItem_Click"
Resources="{StaticResource cartitembutton}" >
<Image Source="/Resources/Icons/delete.png" ></Image>
</Button>
</Viewbox>
</Grid>
</Viewbox>
</DataTemplate>
</ListView.ItemTemplate>
解决方案
您应该使用数据绑定来检索所选项目。源属性将在ListView.SelectedItem
更改时自动更新。
触摸的处理方式与单击的处理方式相同。该框架将触摸事件转换为鼠标事件。
我注意到您将每个元素都包装成一个ViewBox
. 这不是必需的,只会降低性能。当元素托管在 aGrid
中时,默认情况下它们会自动调整大小。例外是需要初始大小的元素,例如Shape
or Image
。但由于项目容器不会自行调整大小,因此容器的内容也不会调整大小。
要强制所有元素占据最大水平空间,您可以设置以Style
项目容器为目标的 a:
<ListView.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
主窗口.xaml.cs
public partial class MainWindow : Window
{
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register(
"Items",
typeof(ObservableCollection<Item>),
typeof(MainWindow),
new PropertyMetadata(default(ObservableCollection<Item>)));
public ObservableCollection<Item> Items
{
get => (ObservableCollection<Item>) GetValue(MainWindow.ItemsProperty);
set => SetValue(MainWindow.ItemsProperty, value);
}
public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register(
"SelectedItem",
typeof(Item),
typeof(MainWindow),
new PropertyMetadata(default(Item), MainWindow.OnSelectedItemChanged));
public Item SelectedItem
{
get => (Item) GetValue(MainWindow.SelectedItemProperty);
set => SetValue(MainWindow.SelectedItemProperty, value);
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this.Items = new ObservableCollection<Item>();
// Initialize data source
CreateItems();
}
// Property changed callback of the SelectedItem property
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Reference to instance members in a class scope
var _this = d as MainWindow;
if (e.NewValue is ItemCollection selectedItem)
{
// Handle currently selected item
}
}
}
主窗口.xaml
<Window>
<ListView ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}" />
</Window>
推荐阅读
- javascript - 你总是需要一个模拟激活路由吗?
- html - 如何限制文本字段的最大宽度?
- python - Django:如何在 urlpatterns 中访问其他模型的主键?
- android - 如何自定义谷歌地图以接收特定位置的通知
- c++ - 使用以 CWinThread 作为基础的类 operator()() 调用 std::thread 失败
- java - 如何使用 XMLMapper 使用键值对反序列化 XML
- reactjs - 如何循环 div 内容,而不是 div 本身
- java - 逐步创建多维数组
- reactjs - 使用 multer for aws 时如何解决意外的现场问题?
- stripe-payments - 条纹支付意图