2012-06-14 5 views
1

Я бил головой о и так далее, я не могу справиться с проблемой, с которой я столкнулся.Подход CRUD с RadGridView, DataForm и MVVM-light

Scenario : У меня есть страница SalesOrder, я пытаюсь использовать эту страницу для создания новых заказов на продажу, а также для редактирования существующих. SalesOrder Страница с другими элементами управления, которые привязаны к текущему заказу клиента, RadGridView и DataForm. Оба связаны с одной и той же Observable Collection в MVVM.

Проблема я столкнулся в том, что,

1) DataForm и сетка привязывается к коллекции все в порядке, но Edit Button, связанного с DataForm Edit Command отключен. Включена только новая кнопка.

2) После добавления нового элемента в форму данных кнопка Edit включена, НО независимо от того, какую строку я выбрал, она ВСЕГДА редактирует первую строку, которая была вставлена, и если я не вставляю строку, я не могу редактировать какую-либо существующие строки. Кажется, что DataForm действительно не знает о существующих строках в коллекции !!!

My Implimentation : Я использую MVVM-свет и следующее, связанные куски моего кода:

**ViewModel**

ниже qsdcvSOPDoc является QueryableSouceDomainCollectionView (обертка источника данных домена для MVVM), продажи заказа Сущности в модели называется 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 является Obserable Collection, которая заселена 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 объекта заполняется текущим заказом клиента, различные элементы управления в View связывается с этим.

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

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

PageMode установлен перед тем как попасть на эту страницу, это устанавливается либо «New» или «Edit», и это помогает в качестве проверки для выполнения загрузки и сохранения команд, а также вызвать некоторые события установки значений по умолчанию ,

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

Посмотреть

The 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}"/> 

Add в г Edit кнопки связаны с командами 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 и сетка привязывается к коллекции все в порядке, но Edit Button неизбежно DataForm Команда редактирования отключена. Включена только новая кнопка.

2) После добавления нового элемента в DataForm, Edit кнопка включена, но независимо от того, какая строка я выбран, он ВСЕГДА отредактировать первую строку, которая была установлена, и если я не вставить строку, я не могу Отредактируйте любые существующие строки. Кажется, что DataForm действительно не знает о существующих строках в коллекции !!!

Я знаю, что могут быть принципиальные ошибки в вышеприведенном подходе, или может быть весь подход неправильный, но именно поэтому я ищу помощь !! любые предложения даже по другим подходам, которые включают в себя CRUD, Dataform и Grid с поддержкой MVVM, будут очень оценены.

+0

Это самый длинный я ждал ответа на StackOverFlow, мой вопрос нечетко сформулирован или не представлен надлежащим образом? или слишком расплывчатым, чтобы понять? или может быть Избрание слишком занято :), пожалуйста, дайте мне знать, если я могу улучшить свой вопрос !!! спасибо – Thr3e

ответ

1

Ну, наконец, я нашел способ приблизиться к приведенному выше, и с помощью другого вопроса, который я разместил на SO Here.

что я на самом деле есть, объявлен DomainContext ctx, а затем я загрузил его заказами продаж через DomainDataSource1, а другой DomainDataSource2 загрузил детали заказа. Оба они связаны с сеткой и формой данных соответственно. После редактирования и добавления записей я только что вызвал ctx.SaveChanges, который сохранил все изменения для ВСЕХ загруженных объектов обратно в защищенный метод Ria.Entity.AcceptChanges(). Thats IT ...

ЗАКЛЮЧЕНИЕ: Не имеет значения, сколько DomainDataSources мы используем для загрузки данных в контекст, если вы хотите сохранить их все вместе, используйте для них все SINGLE DomainContext. Используйте только saperate DomainContexts, если вы собираетесь использовать частично SubmitChanges :).

Еще нужно уточнение? комментировать меня .......

 Смежные вопросы

  • Нет связанных вопросов^_^