我一直在不停地敲打我的头,我似乎无法解决我面临的问题。
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}"/>
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 和 Grid 可以绑定到集合,但是绑定到 DataForm 编辑命令的编辑按钮被禁用。仅启用新按钮。
2)向数据表单添加新项目后,Edit
按钮已启用,但无论我选择了哪一行,它总是编辑插入的第一行,除非我插入一行,否则我无法编辑任何现有行。似乎 DataForm 并没有真正意识到集合中的任何现有行!
我知道上面的方法可能存在原则错误,或者可能整个方法都是错误的,但这就是我寻求帮助的原因!!任何建议,即使是涉及 CRUD、数据表单和支持 MVVM 的网格的不同方法建议,将不胜感激。