c# - 使用 Gong 拖放对 ICollectionView 中的 Observable 集合进行排序
问题描述
我目前正在尝试创建一个 WPF/C#/EF6 应用程序,该应用程序将模拟看板以跟踪具有目标完成日期的任务。我正在使用 Gong-WPF-Drag-Drop nuget 包来允许在泳道之间进行良好的拖放。
该计划的核心围绕 2 个模型,泳道和工作(以下课程的相关部分)。我使用数据库优先的方法来生成这些模型。当通过辅助方法检索 Swimlane 信息时,Jobs 集合由 Observable 集合填充。
泳道
public partial class Swimlane : BaseModel
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Swimlane()
{
this.Jobs = new HashSet<Job>();
}
private int _slId;
public int SlId
{
get { return _slId; }
set { SetProperty(ref _slId, value); }
}
private int _clientId;
public int ClientId
{
get { return _clientId; }
set { SetProperty(ref _clientId, value); }
}
private string _slName;
public string SlName
{
get { return _slName; }
set { SetProperty(ref _slName, value); }
}
private int _sortOrder;
public int SortOrder
{
get { return _sortOrder; }
set { SetProperty(ref _sortOrder, value); }
}
public virtual Client Client { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Job> Jobs { get; set; }
}
工作
public partial class Job : BaseModel
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Job()
{
}
private int _jobId;
public int JobId
{
get { return _jobId; }
set { SetProperty(ref _jobId, value); }
}
private int _clientId;
public int ClientId
{
get { return _clientId; }
set { SetProperty(ref _clientId, value); }
}
private Nullable<int> _assignedSwimLane;
public Nullable<int> AssignedSwimLane
{
get { return _assignedSwimLane; }
set { SetProperty(ref _assignedSwimLane, value); }
}
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
private string _owner_Fn;
public string Owner_Fn
{
get { return _owner_Fn; }
set { SetProperty(ref _owner_Fn, value); }
}
private string _owner_Ln;
public string Owner_Ln
{
get { return _owner_Ln; }
set { SetProperty(ref _owner_Ln, value); }
}
private string _owner_Email;
public string Owner_Email
{
get { return _owner_Email; }
set { SetProperty(ref _owner_Email, value); }
}
private string _owner_Phone;
public string Owner_Phone
{
get { return _owner_Phone; }
set { SetProperty(ref _owner_Phone, value); }
}
private Nullable<System.DateTime> _scheduledIn;
public Nullable<System.DateTime> ScheduledIn
{
get { return _scheduledIn; }
set { SetProperty(ref _scheduledIn, value); }
}
private Nullable<System.DateTime> _actualIn;
public Nullable<System.DateTime> ActualIn
{
get { return _actualIn; }
set { SetProperty(ref _actualIn, value); }
}
private Nullable<System.DateTime> _scheduledCompletion;
public Nullable<System.DateTime> ScheduledCompletion
{
get { return _scheduledCompletion; }
set { SetProperty(ref _scheduledCompletion, value); }
}
private Nullable<System.DateTime> _actualCompletion;
public Nullable<System.DateTime> ActualCompletion
{
get { return _actualCompletion; }
set { SetProperty(ref _actualCompletion, value); }
}
private Nullable<System.DateTime> _scheduledDelivery;
public Nullable<System.DateTime> ScheduledDelivery
{
get { return _scheduledDelivery; }
set { SetProperty(ref _scheduledDelivery, value); }
}
private Nullable<System.DateTime> _actualDelivery;
public Nullable<System.DateTime> ActualDelivery
{
get { return _actualDelivery; }
set { SetProperty(ref _actualDelivery, value); }
}
private Nullable<int> _sortOrder;
public Nullable<int> SortOrder
{
get { return _sortOrder; }
set { SetProperty(ref _sortOrder, value); }
}
}
应用程序将使用在视图模型中创建的 ICollectionView 按其订单号对泳道进行排序。如果不破坏拖放功能,我无法实现的部分是将排序顺序/过滤器应用于每个通道内的作业。
泳道的视图模型检索和iCollectionView的创建
private ObservableCollection<Swimlane> _boardColumns;
public ObservableCollection<Swimlane> BoardColumns
{
get { return _boardColumns; }
set { _boardColumns = value; NotifyPropertyChanged("BoardColumns"); }
}
private ICollectionView _swimlaneCollection;
public ICollectionView SwimlaneCollection
{
get { return _swimlaneCollection; }
set { _swimlaneCollection = value; NotifyPropertyChanged("SwimlaneCollection"); }
}
private async void InitializeVmAsync()
{
BoardColumns = await Utils.SwimlaneHelper.GetAllSwimlanes();
SignalrDelegator = new Utils.Signalr.SignalrHubDelegator(this);
BindingOperations.EnableCollectionSynchronization("BoardColumns", _boardColumnsLock);
SwimlaneCollection = CollectionViewSource.GetDefaultView(BoardColumns);
SwimlaneCollection.Filter = ViewFilter;
SwimlaneCollection.SortDescriptions.Add(new SortDescription("SortOrder", ListSortDirection.Ascending));
}
我已使用 XAML 方法为每个泳道的作业集创建 ICollectionView,并对其应用默认排序。但是,这会破坏 gong 包的拖放功能。它不再让我在泳道上拖放。
XAML
<ItemsControl ItemsSource="{Binding SwimlaneCollection}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<materialDesign:ColorZone Grid.Row="0" Mode="PrimaryDark" Padding="16" CornerRadius="4"
materialDesign:ShadowAssist.ShadowDepth="Depth3" Margin="8">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" Text="{Binding SlName}"
Style="{StaticResource MaterialDesignTitleTextBlock}" />
<TextBlock Grid.Column="0" Grid.Row="1" VerticalAlignment="Center"
Text="{Binding Jobs, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource HoursCountConverter}}"
Style="{StaticResource MaterialDesignSubheadingTextBlock}"/>
<TextBlock Grid.Column="1" Grid.Row="0" VerticalAlignment="Center"
Text="{Binding Jobs.Count, UpdateSourceTrigger=PropertyChanged, StringFormat={}({0}) }"
Style="{StaticResource MaterialDesignSubheadingTextBlock}"/>
</Grid>
</materialDesign:ColorZone>
<ListView VerticalContentAlignment="Top"
HorizontalContentAlignment="Stretch"
VirtualizingStackPanel.IsVirtualizing="True"
ScrollViewer.CanContentScroll="True"
Grid.Row="1"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropHandler="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DockPanel}}}"
dd:DragDrop.UseDefaultEffectDataTemplate="True"
dd:DragDrop.UseDefaultDragAdorner="True">
<ListView.Resources>
<CollectionViewSource x:Key="JobsCvs" Source="{Binding Jobs}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="SortOrder" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</ListView.Resources>
<ListView.ItemsSource>
<Binding Source="{StaticResource JobsCvs}"/>
</ListView.ItemsSource>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel VerticalAlignment="Top" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ListView.ItemTemplate >
<DataTemplate >
<views:Card/>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Template>
<ControlTemplate>
<ScrollViewer Focusable="False" Width="190">
<ItemsPresenter SnapsToDevicePixels="True" Margin="-5" />
</ScrollViewer>
</ControlTemplate>
</ListView.Template>
</ListView>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
如何更改我的方法以保留 ICollectionView 的排序和过滤选项,但仍启用泳道之间和泳道内的拖放?我无法找到很多信息来显示使用 ICollectionViews 在集合中操作集合。
解决方案
我通过不实现排序(因为我想要内部拖放)并在视图 CollectionChanged 事件上放置一个处理程序来处理这个问题。这使我能够为集合中的项目设置属性。
推荐阅读
- python - 如何在 FLASK 中将 url 作为 REST GET 参数传递
- azure - 哪种 azure 服务计划最适合托管高流量的 SPA
- sql - 尝试使用 sqlalchemy 将 sql 表迁移到新格式。几行之后,它在一个给出错误“ORA-00911:无效字符”时失败
- jenkins - Jenkins 项目无法连接到存储库
- r - 将2个向量组合成R中的矩阵时如何保留/分配行名和列名
- python - 如何获取Dataframe中最大值和最小值的上一个和下一个值
- php - 如何在php网页上显示两个表格数据
- c - inet_ntop() 未在此范围内清除
- python - Scikit-Learn + Scipy.optimize 高斯过程回归中的外部优化器
- xml - 从结构生成特定格式的 XML