2014-07-23 84 views
1

我的MVVM WPF應用程序的GridView動態創建列目前已結合到一個ViewModel財產,已在XAML中定義的列一個GridView:在WPF MVVM

<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兩種不同的項目類型:一個「訂單」對象和一個布爾值,用於控制是否對於此特定視圖「已選擇」。

然而,「選擇」屬性尚未建模很好。顯而易見,每個訂單需要多個「選定」屬性,具體取決於訂單中的日期數量,可以是1到5之間。

要在UI模型這個,我需要與創建順序每個日期類似的複選框GridviewColumn動態構造來取代單個複選框GridViewColumn。因此,GroupedOrders變成了Tuple <Order, List<bool>>,並且列表中的每個布爾都需要一列。

在任何給定的情況下,該列表的大小將是網格中的所有訂單相同。但是,如果用戶將新數據加載到網格中,則列表的大小將會改變。

不過,我看不出如何在MVVM做到這一點。現有的解決方案似乎適用於代碼隱藏的情況,即GridView可以作爲對象抓取並即時操作。我見過的唯一的MVVM解決方案是使用一個Converter來動態構建整個GridView,這對於這種情況似乎是巨大的矯枉過正,在GridView中有很多列,但只有一小部分需要動態。

還有別的辦法嗎?

+0

背後,你能不能請進一步解釋有關'多個 「選擇」 properties'?這是'Dictionary '種類,每行將有「多選的屬性」相同的計數? –

+0

@YuliamChandra謝謝!它目前是Tuple ,但效果大致相同。它需要成爲一個元組<訂單,列表>,以便每個日期可以獨立選擇。對於給定的實例,每行都有相同的日期數量,但如果用戶將一些新數據加載到數據網格中,它可能會更改。我編輯了這個問題來反映這一點。是否有意義? –

+1

嗯..如果'States'是一個Order中的一個集合,那麼這個列就是一個綁定到State的'ListView'? State是一個包含Name(字符串)和Value(布爾)屬性的類嗎? –

回答

1

不知道這是你所期望的,但是這是我能想到的。

查看

<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; } 
} 

結果

Result