我知道这是一个非常具体的问题,但我正在努力掌握CSLA框架。我已经成功加载了“Sample N-Tier”应用程序,可以在这里找到:
http://lhotka.net/files/csla40/CslaSamples-4.3.13.zip
Sample N-Tier silverlight应用程序允许您将LineItem对象添加到集合LineItems,它与Customer Name和Customer ID字段组成Order对象。
我正在尝试扩展应用程序的功能,使其成为可删除订单项的练习。下面的代码来自OrderVM.cs文件,并定义了“添加”按钮单击事件的功能。它调用Model.LineItems.AddNew()方法,该方法不接受任何参数。我想删除选中的 LineItem,而不仅仅是第一项,因为我现在已经编码了。我的代码有效,但我无法弄清楚如何检索LineItem对象或我当前选择的行的索引/ id。
namespace SilverlightUI
{
public class OrderVm : ViewModel<BusinessLibrary.Order>
{
public OrderVm()
{
//BeginRefresh(BusinessLibrary.Order.NewOrder);
BeginRefresh(callback => BusinessLibrary.Order.GetOrder(231, callback));
}
protected override void OnError(Exception error)
{
Bxf.Shell.Instance.ShowError(error.Message, "Error");
}
public override void AddNew(object sender, ExecuteEventArgs e)
{
Model.LineItems.AddNew();
}
public override void Remove(object sender, ExecuteEventArgs e)
{
//Bxf.Shell.Instance.ShowError(Model.LineItems.AllowRemove.ToString(), "Delete");
if(Model.LineItems.Count>0)
Model.LineItems.RemoveAt(0);
}
}
}
有人可以解释如何从选定的DataGrid行中检索LineItem对象吗?
谢谢!
编辑:下面发布的是OrderEdit.xaml文件的XAML。
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:csla="clr-namespace:Csla.Xaml;assembly=Csla.Xaml"
xmlns:cslaRules="clr-namespace:Csla.Rules;assembly=Csla"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:my="clr-namespace:SilverlightUI"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:c="clr-namespace:System.Windows.Controls;assembly=System.Windows"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
x:Class="SilverlightUI.OrderEdit"
mc:Ignorable="d"
d:DesignHeight="410" d:DesignWidth="667"
Loaded="UserControl_Loaded">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="./Themes/CslaSampleResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<CollectionViewSource x:Key="orderVmViewSource" d:DesignSource="{d:DesignInstance my:OrderVm, CreateList=True}" />
<CollectionViewSource x:Key="orderVmLineItemsViewSource" Source="{Binding LineItems, Source={StaticResource orderVmViewSource}}" />
</ResourceDictionary>
</UserControl.Resources>
<Border Padding="0,10,0,0" CornerRadius="10,10,0,0">
<Border.Background>
<LinearGradientBrush EndPoint="1.005,0.5" StartPoint="0,0.5">
<GradientStop Color="#7FFFFFFF" Offset="0"/>
<GradientStop Color="#99FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource orderVmViewSource}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="Customer Id:" Grid.Column="0" Grid.Row="0" Style="{StaticResource LabelTextStyle}" />
<TextBox Grid.Column="1" Grid.Row="0" x:Name="idTextBox" Text="{Binding Model.Id, Mode=OneWay}" Style="{StaticResource TextBoxStyle}" />
<TextBlock Text="Customer Name:" Grid.Column="0" Grid.Row="1" Style="{StaticResource LabelTextStyle}" />
<TextBox Grid.Column="1" Grid.Row="1" x:Name="customerNameTextBox" Text="{Binding Model.CustomerName, Mode=TwoWay, ValidatesOnNotifyDataErrors=False}" Style="{StaticResource TextBoxStyle}" />
<!--<csla:PropertyInfo Property="{Binding Path=Model.CustomerName}" x:Name="pi" />-->
<TextBlock Grid.Row="2" Grid.ColumnSpan="2" Text="orders" Style="{StaticResource SubHeadingTextStyle}" Margin="10,15,0,0" />
<sdk:DataGrid Grid.Row="3" Grid.ColumnSpan="2"
AutoGenerateColumns="False"
ItemsSource="{Binding Model.LineItems}"
x:Name="lineItemsDataGrid"
RowDetailsVisibilityMode="VisibleWhenSelected"
RowBackground="{x:Null}"
BorderBrush="{x:Null}"
HorizontalGridLinesBrush="{x:Null}"
VerticalGridLinesBrush="{x:Null}"
GridLinesVisibility="None"
Background="White"
ColumnHeaderHeight="35"
ColumnHeaderStyle="{StaticResource DataGridHeaderStyle}"
RowStyle="{StaticResource DataGridRowStyle}"
CellStyle="{StaticResource DataGridCellStyle}">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn x:Name="idColumn" Binding="{Binding Id}" Header="ID" Width="Auto" />
<sdk:DataGridTextColumn x:Name="nameColumn" Binding="{Binding Name}" Header="NAME" Width="*" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<Button Grid.Row="3" Grid.Column="1" x:Name="AddNewButton" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,5,10,5" Style="{StaticResource AddButtonStyle}" />
<csla:TriggerAction TargetControl="{Binding ElementName=AddNewButton}" MethodName="AddNew" DataContext="{Binding CurrentItem}" />
<Button Grid.Row="3" Grid.Column="1" x:Name="DeleteButton" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,5,10,5" />
<csla:TriggerAction TargetControl="{Binding ElementName=DeleteButton}" MethodName="Remove" DataContext="{Binding CurrentItem}" />
<Border Grid.Row="4" Grid.ColumnSpan="2" Background="#FFE0E0E0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<StackPanel Grid.Row="4" x:Name="stackPanel1" DataContext="{Binding CurrentItem}" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right" Grid.Column="1">
<Button Content="cancel" x:Name="CancelButton" IsEnabled="{Binding CanCancel}" Margin="3" Style="{StaticResource CslaButtonStyle}" />
<Button Content="save" x:Name="SaveButton" IsEnabled="{Binding CanSave}" Margin="3" Style="{StaticResource CslaButtonStyle}" />
<csla:TriggerAction TargetControl="{Binding ElementName=SaveButton}" MethodName="Save"/>
<csla:TriggerAction TargetControl="{Binding ElementName=CancelButton}" MethodName="Cancel"/>
</StackPanel>
<StackPanel Grid.Row="4" Orientation="Horizontal">
<Rectangle Style="{StaticResource DecoratorRectangle}"/>
<Rectangle Style="{StaticResource DecoratorRectangle}"/>
<Rectangle Style="{StaticResource DecoratorRectangle}"/>
<Rectangle Style="{StaticResource DecoratorRectangle}"/>
</StackPanel>
</Grid>
</Border>
</UserControl>
我相信为了访问在DataGrid中选择的ListItem,我必须以某种方式将DataGrid的SelectedItem属性绑定到我的ViewModel中的属性,我是否正确理解了这一点?
我可以添加类似的内容:
SelectedItem="{Binding ViewModel.SelectedListItem}",
到XAML DataGrid元素,但是我仍然有点不清楚要为绑定属性添加什么来实际让它在我的OrderVm.cs中设置属性......
有人可以帮我解决绑定问题吗?谢谢!
答案 0 :(得分:0)
public override void Remove(object sender, ExecuteEventArgs e)
{
//Bxf.Shell.Instance.ShowError(Model.LineItems.AllowRemove.ToString(), "Delete");
if(Model.LineItems.Count>0)
Model.LineItems.RemoveAt(0);
}
ExecuteEventArgs不会暴露某种参数吗?查看文档,它看起来像'CommandOption'(包含Arg
成员)。你能不能将SelectedItem绑定到TriggerAction的CommandOption?我在CSLA中实际上还没有使用TriggerActions,所以我可能会自己看看。您必须能够绑定命令的参数,以便命令处理程序具有某种上下文
编辑:
在他的博客上查看Rocky的帖子之一:
http://www.lhotka.net/weblog/UsingTheTriggerActionControl.aspx
看起来TriggerAction上有一个Parameter成员,它必须将一个param传递给执行上下文
编辑2:
所以只需将YourControl.SelectedItem
绑定到TriggerAction.MethodParameter
,然后在您的方法中ExecuteEventArgs
应该包含对所选对象的引用。
然后你可以使用
Model.LineItems.Remove(e.???);
不确定成员在事件args上是什么,但你可以解决这个问题:)
答案 1 :(得分:0)
我们有一个使用CSLA的Silverlight应用程序。这是我们的DataGrid中的代码代码,用于删除行(如果它们也选择了多行,则它可以工作):
/// <summary>
/// Removes selected items from the IEditableCollection
/// </summary>
public void RemoveSelectedRows()
{
var item = CurrentItem as IEditableBusinessObject;
// if row is not valid, cancel rather than commit to avoid validation
if (item != null)
{
item.CheckRules();
if (!item.IsValid)
this.CancelEdit();
else
this.CommitEdit();
}
else
{
this.CommitEdit();
}
// _lastErrorRow = -1;
if (SelectedItems.Count == 0)
{
MsgBox.ShowMsg(SharedResources._PleaseSelectRowFirst);
return;
}
var col = ItemsSource as Csla.Core.IEditableCollection;
if (col != null)
{
var deleteItems = SelectedItems.OfType<IEditableBusinessObject>().ToList();
int i = 0;
while (i < deleteItems.Count)
{
col.RemoveChild(deleteItems[i]);
}
}
}
请记住,此处的上下文是此代码位于DataGrid本身。因此,在按钮单击中,您将拥有以下内容:
lineItemsDataGrid.RemoveRows();