1

我一直在不停地敲打我的头,我似乎无法解决我面临的问题。

Scenario : 我有一个销售订单页面,我正在尝试使用此页面来创建新的销售订单,以及编辑现有的销售订单。SalesOrder Page 主机,以及绑定到当前销售订单、RadGridView 和 DataForm 的其他控件。两者都绑定到 MVVM 中的同一个 Observable Collection。

我面临的问题是,

1) DataForm 和 Grid 可以绑定到集合,但是绑定到 DataForm Edit Command 的 Edit Button 是 Disabled。仅启用新按钮。

2)向数据表单添加新项目后,Edit按钮已启用,但无论我选择了哪一行,它总是编辑插入的第一行,除非我插入一行,否则我无法编辑任何现有行。似乎 DataForm 并没有真正意识到集合中的任何现有行!

My Implimentation :我正在使用 MVVM-light,以下是我的代码的相关块:

**ViewModel**

下面qsdcvSOPDoc是QueryableSouceDomainCollectionView(mvvm域数据源的封装),Model中的Sales Order Entity叫做SOPDoc

   public const string qsdcvSOPDocPropertyName = "qsdcvSOPDoc";
   private QueryableDomainServiceCollectionView<SOPDoc> _qsdcvSOPDoc;
   public QueryableDomainServiceCollectionView<SOPDoc> qsdcvSOPDoc
    {
        get
        {
            return _qsdcvSOPDoc;
        }

        set
        {
            if (_qsdcvSOPDoc == value)
            {
                return;
            }

            var oldValue = _qsdcvSOPDoc;
            _qsdcvSOPDoc = value;
            RaisePropertyChanged(qsdcvSOPDocPropertyName, oldValue, value, true);

下面ocSalesOrderItemsList是由 IEnumerable、SOPDoc 的子实体填充的可观察集合,其中 SOPDoc.SOPDocDetails

    public const string ocSalesOrderItemsListPropertyName = "ocSalesOrderItemsList";
    private ObservableCollection<SOPDocDetail> _ocSalesOrderItemsList;
    public ObservableCollection<SOPDocDetail> ocSalesOrderItemsList
    {
        get
        {
            return _ocSalesOrderItemsList;
        }

        set
        {
            if (_ocSalesOrderItemsList == value)
            {
                return;
            }

            var oldValue = _ocSalesOrderItemsList;
            _ocSalesOrderItemsList = value;
            RaisePropertyChanged(ocSalesOrderItemsListPropertyName, oldValue, value, true);
        }
    }

qsdcvSOPDoc加载数据时,entCurrentOrder实体填充当前销售订单,视图中的不同控件绑定到此。

    public const string entCurrentOrderPropertyName = "entCurrentOrder";
    private SOPDoc _entCurrentOrder; public SOPDoc entCurrentOrder
    {
        get
        {
            return _entCurrentOrder;
        }

        set
        {
            if (_entCurrentOrder == value)
            {
                return;
            }
            _entCurrentOrder = value;
            RaisePropertyChanged(entCurrentOrderPropertyName);
        }
    }

PageMode在导航到此页面之前设置,设置为“新建”或“编辑”,它有助于检查执行加载和保存命令以及触发一些设置默认值的事件。

    public const string PageModePropertyName = "PageMode";
    private string _pageMode;
    public string PageMode
    {
        get
        {
            return _pageMode;
        }

        set
        {
            if (_pageMode == value)
            {
                return;
            }
            _pageMode = value;
            RaisePropertyChanged(PageModePropertyName);
        }
    }

CurrentSalesOrderId在导航到此页面时设置。

    public const string CurrentSalesOrderIdPropertyName = "CurrentSalesOrderId";
    private int _currentSalesOrderId;
    public int CurrentSalesOrderId
    {
        get
        {
            return _currentSalesOrderId;
        }

        set
        {
            if (_currentSalesOrderId == value)
            {
                return;
            }

            var oldValue = _currentSalesOrderId;
            _currentSalesOrderId = value;
            RaisePropertyChanged(CurrentSalesOrderIdPropertyName, oldValue, value, true);
        }
    }

Constructor of ViewModel

 public SalesOrderViewModel()
    {          
            ctx = new KERPDomainContext();
            var ctxDetail = new KERPDomainContext();

            qry = ctx.GetSalesOrderByIdQuery(CurrentSalesOrderId);
            qsdcvSOPDoc = new QueryableDomainServiceCollectionView<SOPDoc>(ctx, qry);
            qsdcvSOPDoc.Load();
            qsdcvSOPDoc.LoadedData += qsdcvSOPDoc_LoadedData;

            ocSalesOrderItemsList = new ObservableCollection<SOPDocDetail>();
            ocSalesOrderItemsList.CollectionChanged += ocSalesOrderItemsList_CollectionChanged; // This will re-calculate the GrossAmount

           //Commands Binding
            SaveSalesOrder = new RelayCommand(SaveSalesOrderExecute, SaveSalesOrderCanExecute);


        }
    }


 void qsdcvSOPDoc_LoadedData(object sender, LoadedDataEventArgs e)
    {

        entCurrentOrder = (SOPDoc)e.Entities.FirstOrDefault();

        if (PageMode == Enums.SODModes.New.ToString() && CurrentSalesOrderId <= 0)
        { // this is a new Sales Order

            if (entCurrentOrder != null)
                ocSalesOrderItemsList.AddRange((entCurrentOrder.SOPDocDetails.Where(i => i.IsActive == true))); // Adds all active items to the collection list

           // setting some values, the property decleration i omitted here for brevity 
           GrossAmount = 0;
            Carriage = 0;
            Discount = 0;

        }


        if (PageMode == Enums.SODModes.Edit.ToString() && CurrentSalesOrderId > 0)
        {
            if (entCurrentOrder != null)
            {
                ocSalesOrderItemsList.AddRange(entCurrentOrder.SOPDocDetails);

                GrossAmount = entCurrentOrder.SOPDocDetails.Sum(i => i.NetAmount);
                Carriage = entCurrentOrder.Carriage;
                Discount = entCurrentOrder.Discount;
            }
        }
    }

看法

View 有一个 RadGridView 控件和一个 dataform 控件,它们都绑定到相同的 ItemSource 和 CurrentItem:

  <telerik:RadGridView ItemsSource="{Binding ocSalesOrderItemsList}"  Grid.Row="1"                            
                         AutoExpandGroups="True" AutoGenerateColumns="False" ColumnWidth="*" CurrentItem="{Binding entSOPDocDetail}" IsSynchronizedWithCurrentItem="True" IsReadOnly="False">

            <telerik:RadGridView.Columns>
                <telerik:GridViewDataColumn Header="Product Code" DataMemberBinding="{Binding ProductCode}" Width="1.5*"/>
                <telerik:GridViewDataColumn Header="Description" DataMemberBinding="{Binding Description}" Width="5*"/>
                <telerik:GridViewDataColumn Header="Qty" DataMemberBinding="{Binding Qty}" Width="*"/>
                <telerik:GridViewDataColumn Header="UnitType" DataMemberBinding="{Binding UnitType}"/>
                <telerik:GridViewDataColumn Header="Unit Price" DataMemberBinding="{Binding UnitPrice}" DataFormatString="{}{0:0,0.00}"/>
                <telerik:GridViewDataColumn Header="Line Total" DataMemberBinding="{Binding NetAmount}" DataFormatString="{}{0:0,0.00}"/>
                <telerik:GridViewColumn Width="90">
                    <telerik:GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <telerik:RadButton Content="Delete" Command="telerik:RadGridViewCommands.Delete" CommandParameter="{Binding}" />
                        </DataTemplate>
                    </telerik:GridViewColumn.CellTemplate>
                </telerik:GridViewColumn>
            </telerik:RadGridView.Columns>           
    </telerik:RadGridView>

  <telerik:RadDataForm x:Name="dataForm"
                         ItemsSource="{Binding ocSalesOrderItemsList}" 
                         CommandButtonsVisibility="Cancel,Commit" 
                         AutoGenerateFields="False"
                         ValidationSummaryVisibility="Collapsed"
                         EditEnded="RadDataForm_EditEnded"
                         CurrentItemChanged="OnDataFormCurrentItemChanged"
                         LabelPosition="Above"
                         EditTemplate="{StaticResource SOItemsEditTemplate}"
                         NewItemTemplate="{StaticResource SOItemsEditTemplate}" 
                         VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" CurrentItem="{Binding entSOPDocDetail}"/>

AddEdit按钮绑定到 DataForm 命令:

      <telerik:RadButton RenderTransformOrigin="0.5,0.5" Style="{StaticResource smallCommandCircleRadButtons}" Tag="EDIT"
                               Command="telerik:RadDataFormCommands.BeginEdit" CommandTarget="{Binding ElementName=dataForm}" />


      <telerik:RadButton RenderTransformOrigin="0.5,0.5" Style="{StaticResource smallCommandCircleRadButtons}" Margin="0,0,40,0" Tag="ADD ITEM" 
                               Command="telerik:RadDataFormCommands.AddNew" CommandTarget="{Binding ElementName=dataForm}" />

再次 - 问题我面临的问题是,1)DataForm 和 Grid 可以绑定到集合,但是绑定到 DataForm 编辑命令的编辑按钮被禁用。仅启用新按钮。

2)向数据表单添加新项目后,Edit按钮已启用,但无论我选择了哪一行,它总是编辑插入的第一行,除非我插入一行,否则我无法编辑任何现有行。似乎 DataForm 并没有真正意识到集合中的任何现有行!

我知道上面的方法可能存在原则错误,或者可能整个方法都是错误的,但这就是我寻求帮助的原因!!任何建议,即使是涉及 CRUD、数据表单和支持 MVVM 的网格的不同方法建议,将不胜感激。

4

1 回答 1

1

好吧,最后我找到了一种自己解决上述问题的方法,并借助我在 SO Here上发布的另一个问题。

我实际上所做的是,声明了一个 DomainContext ctx,然后我通过它加载了销售订单DomainDataSource1,另一个DomainDataSource2加载了订单详细信息。这两个都分别绑定到 Grid 和 Dataform。在完成所有记录的编辑和添加之后,我只调用ctx.SaveChanges了将所有已加载实体的所有更改保存回 Ria.Entity.AcceptChanges() 保护方法。而已...

结论:无论我们使用多少个 DomainDataSource 将数据加载到上下文中,如果您想将它们全部保存在一起,请DomainContext对所有这些使用 SINGLE。DomainContexts仅当您要使用部分 SubmitChanges时才使用 saperate :)。

还需要澄清吗?评论我.......

于 2012-06-21T07:53:18.560 回答