C# 在具有拖放功能的ListBox中的列表项上触发WPF复选框
我正在使用一个WPF客户端应用程序,它使用一个列表框来显示行程。我的任务是实现拖放功能,以对工作列表中的列表项进行重新排序,从而对行程进行重新排序。工作列表中的每个项目都有自己的视图和视图模型,橙色箭头(启动许可证检查)、红色许可证编号(显示许可证的更多信息)和复选框(选择项目以上载检查或保存更改。还触发列表框视图上的按钮变为活动状态)都位于该视图中。 我已经使用listbox上的代码和PreviewLeftMouseButtonDown触发器完成了拖放。但是,前面提到的触发器似乎使用了复选框的触发器,而不是红色按钮或橙色按钮。但列表框视图上的“全选”按钮仍然有效。C# 在具有拖放功能的ListBox中的列表项上触发WPF复选框,c#,wpf,xaml,triggers,C#,Wpf,Xaml,Triggers,我正在使用一个WPF客户端应用程序,它使用一个列表框来显示行程。我的任务是实现拖放功能,以对工作列表中的列表项进行重新排序,从而对行程进行重新排序。工作列表中的每个项目都有自己的视图和视图模型,橙色箭头(启动许可证检查)、红色许可证编号(显示许可证的更多信息)和复选框(选择项目以上载检查或保存更改。还触发列表框视图上的按钮变为活动状态)都位于该视图中。 我已经使用listbox上的代码和PreviewLeftMouseButtonDown触发器完成了拖放。但是,前面提到的触发器似乎使用了复选框
以下是列表项的XAML代码,该代码被压缩为仅显示复选框代码:
<StackPanel Grid.Row="0" Grid.Column="0" Grid.RowSpan="3">
<CheckBox ClickMode="Press" IsTabStop="False" Style="{DynamicResource CheckBoxStyle}" HorizontalAlignment="Left" VerticalAlignment="Top" IsChecked="{Binding IsSelected,Mode=TwoWay,FallbackValue='False'}" Margin="0 2 0 0"></CheckBox>
<Border BorderBrush="{DynamicResource GrayBorder}" BorderThickness="0 0 1 0"/>
</StackPanel>
以下是红色许可证编号框的代码,可供比较:
<StackPanel Grid.Row="0" Grid.Column="1" Margin="4 4 4 4">
<StackPanel Orientation="Horizontal">
<Button IsTabStop="False" ClickMode="Press" Command="{Binding PermitDetailViewCommand}" CommandParameter="{Binding RequestInfo.PermitNumber}" Style="{StaticResource PermitDetailButton}" Content="{Binding RequestInfo.PermitNumber, Mode=OneTime,FallbackValue=''}"/>
<Button Style="{StaticResource CriticalIconStyle}" Visibility="{Binding RequestInfo.IsCritical, Converter={StaticResource BooleanToVisibility}}" Margin="0,4,0,0" ToolTip="{Binding RequestInfo.CriticalInformation}" Height="14" IsTabStop="False"/>
<Button Style="{StaticResource ContactIconStyle}" Content="{Binding RequestInfo.ContactAttemptedCountCode}" Visibility="{Binding RequestInfo.ContactAttemptedCountCode, Converter={StaticResource StringToVisibility}}" Margin="0,2,0,0" IsTabStop="False"/>
</StackPanel>
</StackPanel>
下面是实例化列表框中每个项目的XAML代码:
<ListBox Margin="4,8" ItemsSource="{Binding Path=CheckedOutVM,Mode=TwoWay,IsAsync=True}"
SelectedItem="{Binding Path=SelectedLocalPermit}" Grid.Row="1" Grid.Column="0" BorderThickness="0"
KeyboardNavigation.TabNavigation="Continue" Name="RequestCheckedOutV" BorderBrush="{DynamicResource DarkBorder}" attprop:ArrowKeyPressed.IsEnabled="True">
<i:Interaction.Triggers>
<i:EventTrigger EventName="ClickMode.Press">
<cmd:EventToCommand
Command="{Binding SelectedLocalCommand}"
CommandParameter="{Binding SelectedItem}"
/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Control.HorizontalContentAlignment" Value="Center"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
<Setter Property="Control.VerticalContentAlignment" Value="Top"/>
<Setter Property="AllowDrop" Value="True"/>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="S_PreviewMouseLeftButtonDown"/>
<EventSetter Event="Drop" Handler="listbox1_Drop"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}" >
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate >
<ContentControl Content="{Binding}" IsTabStop="False"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
下面是列表框中允许拖放的代码:
public partial class WorklistSmallView : UserControl
{
WorklistSmallViewModel vm = new WorklistSmallViewModel();
/// <summary>
/// Initializes a new instance of the WorklistSmallView class.
/// </summary>
public WorklistSmallView()
{
InitializeComponent();
}
private void S_PreviewMouseLeftButtonDown(object sender, MouseEventArgs e)
{
WorklistSmallViewModel vm = new WorklistSmallViewModel();
ListBoxItem draggedItem = sender as ListBoxItem;
draggedItem.IsSelected = true;
DragDrop.DoDragDrop(draggedItem, draggedItem.DataContext, DragDropEffects.Move);
vm = RequestCheckedOutV.DataContext as WorklistSmallViewModel;
}
}
void listbox1_Drop(object sender, DragEventArgs e)
{
WorklistSmallDetailViewModel droppedData = e.Data.GetData(typeof(WorklistSmallDetailViewModel)) as WorklistSmallDetailViewModel;
WorklistSmallDetailViewModel target = ((ListBoxItem)(sender)).DataContext as WorklistSmallDetailViewModel;
int removedIdx = RequestCheckedOutV.Items.IndexOf(droppedData);
int targetIdx = RequestCheckedOutV.Items.IndexOf(target);
if (removedIdx < targetIdx)
{
vm = (WorklistSmallViewModel)RequestCheckedOutV.DataContext;
vm.CheckedOutVM.Insert(targetIdx + 1, droppedData);
vm.CheckedOutVM.RemoveAt(removedIdx);
}
else
{
int remIdx = removedIdx + 1;
if (vm.CheckedOutVM.Count + 1 > remIdx)
{
vm.CheckedOutVM.Insert(targetIdx, droppedData);
vm.CheckedOutVM.RemoveAt(remIdx);
}
}
foreach (var item in vm.CheckedOutVM)
{
item.RouteOrder = RequestCheckedOutV.Items.IndexOf(item) + 1;
}
RequestCheckedOutV.Items.Refresh();
}
}
公共部分类WorklistSmallView:UserControl
{
WorklistSmallViewModel vm=新WorklistSmallViewModel();
///
///初始化WorklistSmallView类的新实例。
///
公共工作列表SmallView()
{
初始化组件();
}
private void S_PreviewMouseLeftButtonDown(对象发送器,MouseEventArgs e)
{
WorklistSmallViewModel vm=新WorklistSmallViewModel();
ListBoxItem draggedItem=作为ListBoxItem的发件人;
draggedItem.IsSelected=true;
DragDrop.DoDragDrop(draggedItem、draggedItem.DataContext、DragDropEffects.Move);
vm=RequestCheckedOutV.DataContext作为WorklistSmallViewModel;
}
}
无效列表框1_Drop(对象发送器,DragEventArgs e)
{
WorklistSmallDetailViewModel droppedData=e.Data.GetData(typeof(WorklistSmallDetailViewModel))作为WorklistSmallDetailViewModel;
WorklistSmallDetailViewModel目标=((ListBoxItem)(发件人)).DataContext作为WorklistSmallDetailViewModel;
int removedIdx=RequestCheckedOutV.Items.IndexOf(droppedData);
int-targetIdx=RequestCheckedOutV.Items.IndexOf(目标);
if(移除IDXremIdx)
{
vm.CheckedOutVM.Insert(targetIdx,droppedData);
vm.CheckedOutVM.RemoveAt(remIdx);
}
}
foreach(vm.CheckedOutVM中的变量项)
{
item.RouteOrder=RequestCheckedOutV.Items.IndexOf(item)+1;
}
RequestCheckedOutV.Items.Refresh();
}
}
我感谢任何提供的帮助,如果你需要任何更多的信息,请让我知道
更新#1故障排除尝试和结果
1.从复选框中删除动态样式并使用复选框。结果-复选框中没有更改。似乎事件没有进入ListBox项目,只是它仍然允许单击按钮
因此,在彻底搜索之后,我尝试在事件发生时实现一些逻辑,以消除事件的消耗。我想如果我在事件中使用“如果”语句,而不使用其他语句 我还发现我需要两个事件触发器来完成这项工作。下面是我在视图中使用的事件触发器:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Control.HorizontalContentAlignment" Value="Center"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
<Setter Property="Control.VerticalContentAlignment" Value="Top"/>
<Setter Property="AllowDrop" Value="True"/>
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="RequestCheckedOutV_PreviewMouseLeftButtonDown"/>
<EventSetter Event="PreviewMouseMove" Handler="RequestCheckedOutV_PreviewMouseMove"/>
<EventSetter Event="Drop" Handler="listbox1_Drop"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}" >
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
PreviewMouseMove处理程序用于比较起点位置和鼠标释放位置,然后将结果与系统参数中预设的最小移动规格进行比较。(我的预设为4)如果超过最小值,处理程序知道这是一个拖放事件,并调用StartDrag并将dragAction设置为true
private void RequestCheckedOutV_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (Mouse.LeftButton == MouseButtonState.Pressed && !dragAction)
{
Point position = e.GetPosition(null);
if (Math.Abs(position.X - _startPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(position.Y - _startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
{
dragAction = true;
this.StartDrag(sender, e);
}
}
}
下面的StartDrag方法实际上调用了DoDragDrop方法。然后,它还将拖动操作变量重置为false,以便在错误中删除它时,可以重置事件
private void StartDrag(object sender, MouseEventArgs e)
{
ListBoxItem draggedItem = sender as ListBoxItem;
draggedItem.IsSelected = true;
DragDrop.DoDragDrop(draggedItem, draggedItem.DataContext, DragDropEffects.Move);
dragAction = false;
}
我的投球手一点也没变。
我不知道这是否是实现这一目标的最佳方式,但它对我来说很有效。我想如果它能为我节省一些时间,希望它也能帮助其他人 如果你去掉复选框中定义的样式,你会得到同样的结果吗?是的,先生。这是我尝试的第一件事。有趣的是,红色按钮仍在工作,那么这是否意味着列表框没有使用事件?嗯,您的红色和橙色按钮是否为
按钮?这可以解释一些事情,因为ListBoxItem继承自ToggleButton
类,而Checkbox
派生自该类。我的意思是有一些简单的解决办法,但让我想想
private void StartDrag(object sender, MouseEventArgs e)
{
ListBoxItem draggedItem = sender as ListBoxItem;
draggedItem.IsSelected = true;
DragDrop.DoDragDrop(draggedItem, draggedItem.DataContext, DragDropEffects.Move);
dragAction = false;
}