CSLA Silverlight项目(C#)样本N层应用程序(添加删除功能)

时间:2012-07-10 21:05:56

标签: c# silverlight business-objects csla

我知道这是一个非常具体的问题,但我正在努力掌握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中设置属性......

有人可以帮我解决绑定问题吗?谢谢!

2 个答案:

答案 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();