Я бил головой о и так далее, я не могу справиться с проблемой, с которой я столкнулся.Подход 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, будут очень оценены.
Это самый длинный я ждал ответа на StackOverFlow, мой вопрос нечетко сформулирован или не представлен надлежащим образом? или слишком расплывчатым, чтобы понять? или может быть Избрание слишком занято :), пожалуйста, дайте мне знать, если я могу улучшить свой вопрос !!! спасибо – Thr3e