分组时将数据保留到收集

时间:2012-09-28 13:07:01

标签: c# wpf xaml listview grouping

我有一个我在ListView中表示的Collection,它由OrderID和Expander分组。

在Expander Header中,我显示了OrderID以及Invoice TextBox。 在实际的ListView.View中,我显示了CustomerName,OrderID和Invoice TextBox。 因此,每行数据都有自己的Invoice TextBox,每个Grouping标题都有一个Invoice TextBox。

当我在Group Header Invoice TextBox中输入一个值时,会自动更新它的成员Invoice TextBoxes。但是各行不会更新分组发票文本框。

Screenshot

从图像中可以看出(这更好地描述了它)

现在,当用户点击“处理所选项目”按钮时,我希望能够使用TextBoxes中的InvoiceID进行Collection更新。所以我需要将分组的行链接到Collection以及GroupHeader行。 这可能吗?

这是代码: WPF

<UserControl x:Class="TestGrouping.MainWindowView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     Height="350" Width="525"
     xmlns:cal="http://www.caliburnproject.org">

<UserControl.Resources>
    <CollectionViewSource x:Key='src' Source="{Binding NewOrders}">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="OrderID" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
    <CollectionViewSource x:Key="OrderGroup" Source="{Binding Path=NewOrders}" />

    <Style x:Key="CustomListViewItemStyle" TargetType="{x:Type ListViewItem}">
        <Style.Triggers>
            <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                <Setter Property="Background" Value="#f6f2f2"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" ShowGridLines="False" >


    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />

    </Grid.RowDefinitions>
    <Button Grid.Column="0" Grid.Row="0" x:Name="ProcessItems" Content="Process Selected Items" HorizontalAlignment="Left" MinWidth="80" cal:Message.Attach="ProcessItems($datacontext)"/>

    <ListView ItemsSource="{Binding Source={StaticResource src}}" BorderThickness="1" Grid.Column="0" Grid.Row="1" Height="580">
        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.ContainerStyle>
                    <Style TargetType="{x:Type GroupItem}">
                        <Setter Property="Margin" Value="0,0,0,5"/>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type GroupItem}">
                                    <Expander IsExpanded="{Binding Mode=TwoWay, Path=IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}" BorderBrush="#FFA4B97F" BorderThickness="1,1,1,1" >
                                        <Expander.Header>
                                            <DockPanel>
                                                <TextBlock FontWeight="Bold" Text="OrderID : "  Margin="5,0,0,0" />
                                                <TextBlock FontWeight="Bold" Text="{Binding Path=Name}"  Margin="5,0,0,0" Width="100"/>
                                                <TextBlock FontWeight="Bold" Text="Count : "  Margin="5,0,0,0" />
                                                <TextBlock FontWeight="Bold"  Text="{Binding Path=ItemCount}" Margin="5,0,0,0" Width="100"/>
                                                <TextBlock FontWeight="Bold"  Text="InvoiceID : " Margin="5,0,0,0" />
                                                <TextBox x:Name="GroupInvoiceID" Margin="5,0,0,0" Width="100" BorderThickness="1" BorderBrush="#FFA4C5E8" />
                                            </DockPanel>
                                        </Expander.Header>
                                        <Expander.Content>
                                            <ItemsPresenter />
                                        </Expander.Content>
                                    </Expander>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </GroupStyle.ContainerStyle>
            </GroupStyle>
        </ListView.GroupStyle>

        <ListView.View>
            <GridView AllowsColumnReorder="False" x:Name="GridView1">
                <GridViewColumn Header="Customer Name" DisplayMemberBinding="{Binding Path=Customer}" ></GridViewColumn>
                <GridViewColumn Header="Order ID" DisplayMemberBinding="{Binding Path=OrderID}" ></GridViewColumn>
                <GridViewColumn Header="Invoice ID">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox x:Name="InvoiceID" HorizontalAlignment="Stretch" Width="100" Text="{Binding ElementName=GroupInvoiceID, Path=Text, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" BorderThickness="1" BorderBrush="#FFA4C5E8" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

            </GridView>
        </ListView.View>

    </ListView>


</Grid>

以下是代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Caliburn.Micro;
using System.Collections.ObjectModel;
using System.Windows;

namespace TestGrouping
{
public class MainWindowViewModel : Conductor<object>
{

    public MainWindowViewModel() {

        List<OrderViewModel> all = new List<OrderViewModel>();
        OrderViewModel ovm = new OrderViewModel();
        ovm.ID = 1;
        ovm.Customer = "cust1";
        ovm.OrderID = "0001";
        all.Add(ovm);
        ovm = new OrderViewModel();
        ovm.ID = 2;
        ovm.Customer = "cust2";
        ovm.OrderID = "0001";
        all.Add(ovm);
        ovm = new OrderViewModel();
        ovm.ID = 3;
        ovm.Customer = "cust3";
        ovm.OrderID = "0002";
        all.Add(ovm);
        ovm = new OrderViewModel();
        ovm.ID = 4;
        ovm.Customer = "cust3";
        ovm.OrderID = "0003";
        all.Add(ovm);

        this.NewOrders = new ObservableCollection<OrderViewModel>(all);
        this.NotifyOfPropertyChange(() => this.NewOrders);
    }

    public ObservableCollection<OrderViewModel> NewOrders { get; private set; }

    public void ProcessItems(object obj)
    {

    }

}


public class OrderViewModel 
{
    public OrderViewModel()
    {

    }

    int _ID;
    public int ID
    {
        get { return _ID; }
        set
        {
            if (value == _ID)
                return;

            _ID = value;

        }
    }

    string _Customer;
    public string Customer
    {
        get { return _Customer; }
        set
        {
            if (value == _Customer)
                return;

            _Customer = value;

        }
    }


    string _OrderID;
    public string OrderID
    {
        get { return _OrderID; }
        set
        {
            if (value == _OrderID)
                return;

            _OrderID = value;
        }
    }

    string _InvoiceNumber;
    public string InvoiceNumber
    {
        get { return _InvoiceNumber; }
        set
        {
            if (value == _InvoiceNumber)
                return;

            _InvoiceNumber = value;
        }
    }

}

}

我知道这很长,但我试图提供尽可能多的信息。 任何帮助都会很棒,或者指向正确的方向。 如果有任何我错过的信息,请大声喊叫。

1 个答案:

答案 0 :(得分:0)

我已经成功解决了这个问题 - 可能不是最优雅的,但我认为它有效。

我在项目TextBox中添加了一个Change事件,它将更新集合。 所以我的Listview.View现在如下:

<ListView.View>
            <GridView AllowsColumnReorder="False" x:Name="GridView1">
                <GridViewColumn Header="Customer Name" DisplayMemberBinding="{Binding Path=Customer}" ></GridViewColumn>
                <GridViewColumn Header="Order ID" DisplayMemberBinding="{Binding Path=OrderID}" ></GridViewColumn>
                <GridViewColumn Header="Invoice ID">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox x:Name="InvoiceID" HorizontalAlignment="Stretch" Width="100" Text="{Binding ElementName=GroupInvoiceID, Path=Text, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" BorderThickness="1" BorderBrush="#FFA4C5E8" 
                                     cal:Message.Attach="[Event TextChanged]=[Action InvoiceID_TextChanged($datacontext, $eventArgs)]" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

            </GridView>
        </ListView.View>

我将以下代码添加到ModelView

public void InvoiceID_TextChanged(object obj, RoutedEventArgs e)
    {
        OrderViewModel ovm = obj as OrderViewModel;
        string invoiceIDText = (e.OriginalSource as TextBox).Text;
        foreach (OrderViewModel o in NewOrders)
        {
            if (o.ID == ovm.ID)
            {
                o.InvoiceNumber = invoiceIDText;
            }
        }
    }

这会使用正确的InvoiceNumber更新集合“NewOrders”。单击“处理项目”按钮后,该集合已更新,现在可以保留到数据库中。

我希望这有助于某人。