StrataFrame Forum

BO.Sort for date

http://forum.strataframe.net/Topic6585.aspx

By Chan - 2/6/2007

Hi,

I try to sort my data in my BO using the code below.

However, it doesn't work. Listview always show the records using PK order. I have listview.sorting = none as well.

Any ideas?

this.itemPricesBO.FillByParentPrimaryKey(this.itemsBO.ItemID);
this.itemPricesBO.Sort = "FromDate ASC";
this.lvItemPrices.Requery();

By Chan - 2/6/2007

Hi,

I checked data in currentdatatable, it doesn't sort.

By Trent L. Taylor - 2/6/2007

You cannot sort a data table, only a data view.  If you want to apply a sort to the BO then set the Sort of the BO or the DefaultView of the data table.

MyBO.Sort = "MySortField"
or
MyDataTable.DefaultView.Sort = "MySortField"

However, if you use the DefaultView, then you will have to populate from the DefaultView as the DataTable does not respect the sort, only the view does.

As for sort a ListView, you can do this a number of ways.  You can use an ORDER BY on your SELECT statement, or you can use ListViewColumnSorter within the framework.  There is a class that will sort the ListView columns for you.

Private _ListSorter As New MicroFour.StrataFrame.UI.Windows.Forms.ListViewColumnSorter(SortOrder.Ascending,0)
Private Sub lvParent_AfterRequery() Handles lvParent.AfterRequery
        Me.lvParent.ListViewItemSorter = _ListSorter
        Me.lvParent.Sort()
End Sub

Private Sub lvParent_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lvParent.ColumnClick
        _ListSorter.SetSort(SortOrder.Ascending, e.Column)
        Me.lvParent.ListViewItemSorter = _ListSorter
        Me.lvParent.Sort()
End Sub

FYI, by default the ListViewColumnSorter will automatically invert from Ascending to Descending if the same column is clicked over and over again.

By Chan - 2/6/2007

Hi,

Thank you for reply.

I have tried myBO.Sort = "FromDate", but it doesn't work.

Also, I need myBO to be sorted is because I would like to show an icon on listview based on previous and current record value. Sorting in listview would not apply in this case.



Any other ideas?



Thank you
By Trent L. Taylor - 2/6/2007

You are sorting the BO outside of the confines of the ListView.  You are going to have to set the Sort of the BO, THEN populate the ListView.  Also, if you are using the PopulationDataSource settings of the ListView, you MUST use the CopyDataFrom method and populate from an already populated BO (which has a sort applied).  You can view the AdvancedList POpulation sample that was installed with StrataFrame to see how to use the CopyDataFrom method.
By Chan - 2/7/2007

Hi,
Yes, I have set

lvPrices.PopulateDataSourceSettings to CopyDataFrom(BusinessLayerBase, BusinessCloneDataType)

lvPrice.PopulateOnFormLoad = 'Manual'

I also have these code

private void ItemPriceMaintenance_Load(object sender, EventArgs e)
{

this.itemPricesBO.FillByParentPrimaryKey(this.itemsBO.ItemID);
this.itemPricesBO.Sort = "fromdate";
this.lvItemPrices.Requery();
}

I also faced very strange things here. If I set something to sort property, my changes to one record would affect the next record also.

private void tsbEdit_Click(object sender, EventArgs e)
{
bool llSuccess;
this.itemPricesBO.NavigateToPrimaryKey(this.lvItemPrices.SelectedItems[0].Tag);
this.itemPricesBO.Edit();
llSuccess = (this.ItemPricechildFormDialog.ShowDialog() == DialogResult.OK);
if (!llSuccess)
{
this.itemPricesBO.Undo(MicroFour.StrataFrame.Business.BusinessUndoType.CurrentRowOnly);
}
else
{
_LastPrice = 0;
this.lvItemPrices.Requery();
}

Childform OK button

private void cmdOK_Click(object sender, EventArgs e)
{
if (this.itemPricesBO.CheckRulesOnRow())
{
DialogResult = DialogResult.OK;
}
}

I try to set expression to currentview.sort directory and view the data, it doesnt sort also.

this.itemPricesBO.CurrentView.Sort
this.itemPricesBO.CurrentView.Table.Rows[0].ItemArray[2]

Any ideas?

By Trent L. Taylor - 2/7/2007

Yes, you have to use the CopyDataFrom(DataTable,..) rather than the CopyDataFrom(BusinessLayerBase,...) because of how you are trying to do your sort.  Then when you provide the first parameter in the ListPopulating event you will provide the CurrentView like this:

e.Parameters(0).Value = MyBO.CurrentView.ToTable()

This will populate using your sort.

By Chan - 2/7/2007

Hi,

OK, the sorting works. Thank you.

However, I hit the strange behavour.

I have price list record as shown below. I select the highlighted record and call myBO.Edit().

If I make changes to "from date" that would cause sorting position changed, the next record "from date" value also would be changed

//Code for screen above.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using JK.Inventory.BusinessObject.Product;

namespace JK.Inventory.UI.Windows.Forms.Product

{

public partial class ItemPriceMaintenance : MicroFour.StrataFrame.UI.Windows.Forms.StandardForm

{

private decimal _LastPrice;

public ItemPriceMaintenance()

{

InitializeComponent();

}

private void cmdOK_Click(object sender, EventArgs e)

{

if (this.itemPricesBO.Save() == MicroFour.StrataFrame.Data.SaveUndoResult.Success)

{

DialogResult = DialogResult.OK;

}

}

private void cmdCancel_Click(object sender, EventArgs e)

{

this.itemPricesBO.Undo(MicroFour.StrataFrame.Business.BusinessUndoType.AllRows);

DialogResult = DialogResult.Cancel;

}

private void tsbAdd_Click(object sender, EventArgs e)

{

bool llSuccess;

this.itemPricesBO.Add();

llSuccess = (this.ItemPricechildFormDialog.ShowDialog() == DialogResult.OK);

if (!llSuccess)

{

this.itemPricesBO.Undo(MicroFour.StrataFrame.Business.BusinessUndoType.CurrentRowOnly);

}

else

{

this.lvItemPrices.Requery();

}

}

private void tsbEdit_Click(object sender, EventArgs e)

{

bool llSuccess;

this.itemPricesBO.NavigateToPrimaryKey(this.lvItemPrices.SelectedItems[0].Tag);

this.itemPricesBO.Edit();

llSuccess = (this.ItemPricechildFormDialog.ShowDialog() == DialogResult.OK);

if (!llSuccess)

{

this.itemPricesBO.Undo(MicroFour.StrataFrame.Business.BusinessUndoType.CurrentRowOnly);

}

else

{

_LastPrice = 0;

this.lvItemPrices.Requery();

}

}

private void tsbRemove_Click(object sender, EventArgs e)

{

this.itemPricesBO.SeekToPrimaryKey(this.lvItemPrices.SelectedItems[0].Tag);

this.itemPricesBO.DeleteCurrentRow(true);

this.lvItemPrices.Requery();

}

private void ItemPriceMaintenance_Load(object sender, EventArgs e)

{

this.itemPricesBO.FillByParentPrimaryKey(this.itemsBO.ItemID);

this.itemPricesBO.Sort = "FromDate";

this.lvItemPrices.Requery();

}

private void lvItemPrices_ListPopulating(MicroFour.StrataFrame.UI.ListPopulatingEventArgs e)

{

e.Parameters[0].Value = this.itemPricesBO.CurrentView.ToTable(); //this.itemPricesBO;

e.Parameters[1].Value = MicroFour.StrataFrame.Business.BusinessCloneDataType.ClearAndFillFromCompleteTable;

}

private void lvItemPrices_RowPopulating(MicroFour.StrataFrame.UI.Windows.Forms.RowPopulatingEventArgs e)

{

ItemPricesBO loItemPriceBO = ((ItemPricesBO)e.BusinessObject);

if (loItemPriceBO.Price > _LastPrice)

{

e.ImageIndex = 0;

}

else if (loItemPriceBO.Price < _LastPrice)

{

e.ImageIndex = 1;

}

_LastPrice = loItemPriceBO.Price;

e.Values[0].DisplayValue = loItemPriceBO.FromDate.ToShortDateString();

//e.Values[1].DisplayValue = loItemPriceBO.ToDate.ToShortDateString();

e.Values[1].DisplayValue = loItemPriceBO.Price.ToString("###,###,##0.00");

e.Values[2].DisplayValue = loItemPriceBO.MinPrice.ToString("###,###,##0.00");

e.Values[3].DisplayValue = loItemPriceBO.MaxPrice.ToString("###,###,##0.00");

/*e.Values[0].DisplayValue = loItemPriceBO.FromDate.ToShortDateString();

e.Values[1].DisplayValue = loItemPriceBO.Price.ToString("###,###,##0.00");

e.Values[2].DisplayValue = loItemPriceBO.MinPrice.ToString("###,###,##0.00");

e.Values[3].DisplayValue = loItemPriceBO.MaxPrice.ToString("###,###,##0.00");

*/

}

private void itemPricesBO_ParentFormLoading()

{

}

}

}

//Code in my editor form.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

namespace JK.Inventory.UI.Windows.Forms.Product

{

public partial class ItemPriceEditor : JK.Inventory.UI.Windows.Forms.Product.PriceEditorBase

{

public ItemPriceEditor()

{

InitializeComponent();

}

private void cmdOK_Click(object sender, EventArgs e)

{

if (this.itemPricesBO.CheckRulesOnRow())

{

DialogResult = DialogResult.OK;

}

}

private void cmdCancel_Click(object sender, EventArgs e)

{

DialogResult = DialogResult.Cancel;

}

}

}

I did anything wrong? Sorry, I am new to .NET.

Thank you

By StrataFrame Team - 2/7/2007

Most likely, when you modify the record, the .NET binding is copying the value back more than once.  The first time, the value is being copied into the record, then the position of the record changes, but the CurrentRowIndex of the business object does not change.  So, when the binding copies the value back into the record again, the correct record is no longer selected. 

When you have a sort set on a business object, it is best to remove the sort while you are editing a record or create a new business object and populate it with only the record that is being edited. 

By Chan - 2/7/2007

You saved my life!!!!

Thank you