我以MVC模式设置了UserControl
,其中包含DataGrid
和List
的模型。我的List
的项目比我的DataGrid
所显示的要多,这就是为什么我一直在寻找一种构建方式,让用户自己选择自己想要的项目。
我的DataGrid应该能够执行以下所有操作:
当我尝试为Pen&Paper游戏DSA(黑眼)构建自定义字符表生成器时,我很乐意使DataGrid尽可能与它们的网格相同。
在这里您可以看到一个网格来选择武器技能。 第一列包含一个组合框,其中包含所有武器技能的名称。 从此框中选择一项技能后,该行将变为该技能的统计信息
我以前只使用DevExpress GridControls,所以即使没有实现功能,我也很难进入“默认” DataGrid。
其他信息:
我该如何按照我的想象来工作/您是否有其他/更轻松的解决方案?
答案 0 :(得分:0)
两个景点:
向行的视图模型添加属性IsShown
,以跟踪记录当前在数据网格中是否可见。我们可以使用RowStyle
来强制执行此操作。
对基于数据网格CollectionView
的组合框使用ItemsSource
。如果未显示该记录,则应该可以从组合框中选择该记录。将过滤器添加到collectionview应该可以解决问题。
WeaponViewModel.cs
public class WeaponViewModel : ViewModelBase
{
private readonly string _name;
private string abbreviation;
private int damage;
private bool isShown;
public WeaponViewModel(string name, string abbreviation, int damage, bool isShown)
{
_name = name;
this.Abbreviation = abbreviation;
this.Damage = damage;
this.IsShown = isShown;
}
public string Name => _name;
public string Abbreviation
{
get { return abbreviation; }
set
{
abbreviation = value;
OnPropertyChanged();
}
}
public int Damage
{
get { return damage; }
set
{
damage = value;
OnPropertyChanged();
}
}
public bool IsShown
{
get { return isShown; }
set
{
isShown = value;
OnPropertyChanged();
}
}
}
MainViewModel.cs
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
Weapons = new ObservableCollection<WeaponViewModel>(GetWeapons());
DropDownWeapons = (CollectionView)new CollectionViewSource { Source = Weapons }.View;
DropDownWeapons.Filter = DropDownFilter;
}
#region DataGrid
public ObservableCollection<WeaponViewModel> Weapons { get; }
private WeaponViewModel currentWeapon;
public WeaponViewModel CurrentWeapon
{
get { return currentWeapon; }
set
{
currentWeapon = value;
OnPropertyChanged();
}
}
#endregion DataGrid
#region ComboBox
public CollectionView DropDownWeapons { get; }
private WeaponViewModel selectedWeapon;
public WeaponViewModel SelectedWeapon
{
get { return selectedWeapon; }
set
{
if (value != null)
{
selectedWeapon = value;
ReplaceCurrentWith(selectedWeapon);
OnPropertyChanged();
}
}
}
private void ReplaceCurrentWith(WeaponViewModel requestedWeapon)
{
currentWeapon.IsShown = false;
requestedWeapon.IsShown = true;
var currentWeaponIndex = Weapons.IndexOf(currentWeapon);
var requestedWeaponIndex = Weapons.IndexOf(requestedWeapon);
Weapons.Move(requestedWeaponIndex, currentWeaponIndex);
DropDownWeapons.Refresh();
}
private bool DropDownFilter(object item)
{
var weapon = (WeaponViewModel)item;
return weapon.IsShown == false;
}
#endregion ComboBox
private static IList<WeaponViewModel> GetWeapons()
{
var weapons = new List<WeaponViewModel>
{
new WeaponViewModel("Assault Rifle", "AR", 30, true),
new WeaponViewModel("Submachine Gun", "SM", 17, true),
new WeaponViewModel("Revolver", "RV", 54, true),
new WeaponViewModel("Shotgun", "AR", 30, true),
new WeaponViewModel("Sniper", "SN", 63, true),
new WeaponViewModel("Rocket Launcher", "RL", 300, true),
new WeaponViewModel("Grenade Launcher", "GL", 200, true),
new WeaponViewModel("Minigun", "MG", 20, true),
new WeaponViewModel("Knife", "KN", 10, false),
new WeaponViewModel("Baseball Bat", "BB", 6, false),
};
return weapons;
}
}
MainWindow.xaml
<Window x:Class="WpfApp.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:WpfApp.ViewModels"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
<DataGrid ItemsSource="{Binding Weapons}" SelectedItem="{Binding CurrentWeapon}"
AutoGenerateColumns="False">
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsShown}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Weapons">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
ItemsSource="{Binding DropDownWeapons}"
SelectedItem="{Binding SelectedWeapon}"
DisplayMemberPath="Name"
IsEditable="False" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" />
<DataGridTextColumn Header="AB" Binding="{Binding Abbreviation}" />
<DataGridTextColumn Header="Damage" Binding="{Binding Damage}" />
</DataGrid.Columns>
</DataGrid>
</Window>