我的 MVVM WPF 应用程序当前有一个绑定(bind)到 ViewModel 属性的 GridView,并具有在 XAML 中定义的列:
<ListView Grid.Row="0" ItemsSource="{Binding GroupedOrders}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Item2, Mode=OneWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Date" DisplayMemberBinding="{Binding Item1.Date, StringFormat={}{0:dd/MM/yyyy}}" />
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Item1.Name}" />
<!-- lots more -->
</GridView>
</ListView.View>
</ListView>
GroupedOrders 是一个包含两种不同项目类型的元组的 ObservableCollection:一个“订单”对象和一个 bool 值,用于控制该特定 View 是否“选择”它。
但是,“选定的”属性尚未建模良好。据了解,每个订单都需要多个“选定”属性,具体取决于订单中的日期数量(可以在 1 到 5 之间)。
为了在 UI 中对此进行建模,我需要将单个 Checkbox GridViewColumn 替换为动态构造,该动态构造为订单中的每个日期创建类似的 Checkbox GridviewColumn。因此 GroupedOrders 变成 Tuple <Order, List<bool>>
相反,列表中的每个 bool 值都需要有一列。
在任何给定实例中,对于网格中的所有订单,该列表的大小都相同。但如果用户将新数据加载到网格中,列表的大小将会改变。
但是,我看不到如何在 MVVM 中执行此操作。现有的解决方案似乎适用于代码隐藏,其中 GridView 可以作为对象抓取并即时操作。我见过的唯一的 MVVM 解决方案是使用 Converter 动态构建整个 GridView,这对于这种情况来说似乎是巨大的杀伤力,因为 GridView 中有很多列,但只有一小部分。需要是动态的。
还有别的办法吗?
最佳答案
不确定这是否是您所期望的,但这是我能想到的。
查看
<ListView ItemsSource="{Binding Orders}">
<ListView.View>
<GridView>
<GridViewColumn Header="State">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ListView ItemsSource="{Binding States}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.Resources>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Value}" Content="{Binding Text}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="OrderNo" DisplayMemberBinding="{Binding OrderNo}" />
</GridView>
</ListView.View>
</ListView>
隐藏代码
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Orders.Add(new Order { OrderNo = "Order001" });
Orders.Add(new Order { OrderNo = "Order002" });
Orders.Add(new Order { OrderNo = "Order003" });
}
private readonly ObservableCollection<Order> _orders = new ObservableCollection<Order>();
public ObservableCollection<Order> Orders
{
get { return _orders; }
}
}
public class Order
{
public Order()
{
States.Add(new State { Text = "Is Paid", Value = false });
States.Add(new State { Text = "Is Delivered", Value = false });
}
public string OrderNo { get; set; }
private readonly ObservableCollection<State> _states = new ObservableCollection<State>();
public ObservableCollection<State> States
{
get { return _states; }
}
}
public class State
{
public string Text { get; set; }
public bool Value { get; set; }
}
结果
关于c# - 在 WPF MVVM 的 GridView 中动态创建列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24912308/