0

我知道这是一个非常具体的问题,但我试图了解 CSLA 框架。我已经成功加载了“Sample N-Tier”应用程序,可以在这里找到:

http://lhotka.net/files/csla40/CslaSamples-4.3.13.zip

示例 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 中设置属性...

有人可以帮我装订什么吗?谢谢!

4

2 回答 2

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

于 2012-07-12T15:03:06.687 回答
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 成员,它必须将参数传递给执行上下文

编辑2:

所以只需绑定YourControl.SelectedItemTriggerAction.MethodParameter,然后在您的方法中ExecuteEventArgs应该包含对所选对象的引用。

然后你可以使用

Model.LineItems.Remove(e.???); 

不确定事件参数上的成员是什么,但你可以解决这个问题:)

于 2012-07-12T11:59:55.587 回答