Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
3160
How to force a datadgrid to refresh
posted

In the code below my itemssource does not change but one of the properties of the control changes, which changes which field is bound.  I need to clear the datagrid items and force it to rebind.  How do I do that?  By the way, onpropertychanged for the Items property is raised but the grid does not rebuild.

Thank you,

 

Sam

using

System;

using

System.Collections.Generic;

using

System.Linq;

using

System.Text;

using

System.Windows;

using

System.Windows.Controls;

using

System.Windows.Data;

using

System.Windows.Documents;

using

System.Windows.Input;

using

System.Windows.Media;

using

System.Windows.Media.Imaging;

using

System.Windows.Navigation;

using

System.Windows.Shapes;

using

System.Collections.ObjectModel;

using

Poolman.Entities;

using

Poolman.Common;

using

Poolman.Models;

using

System.Threading;

using

System.Threading.Tasks;

using

Infragistics.Windows.DataPresenter;

using

Infragistics.Windows.DataPresenter.Events;

using

Infragistics.Controls.Editors;

using

Infragistics.Windows.DockManager;

namespace

Poolman.Controls

{

public partial class ExposureMatrixAccountGrid : Common.

BaseUserControl

{

public IList<ExposureItem

> Items

{

get { return (IList<ExposureItem

>)GetValue(ItemsProperty); }

set { SetValue(ItemsProperty, value

); }

}

public static readonly DependencyProperty

ItemsProperty =

DependencyProperty.Register("Items", typeof(IList<ExposureItem>), typeof(ExposureMatrixAccountGrid), new UIPropertyMetadata(null

,DataChanged));

 

public bool

IsQuantityView

{

get { return (bool

)GetValue(IsQuantityViewProperty); }

set { SetValue(IsQuantityViewProperty, value

); }

}

public static readonly DependencyProperty

IsQuantityViewProperty =

DependencyProperty.Register("IsQuantityView", typeof(bool), typeof(ExposureMatrixAccountGrid), new UIPropertyMetadata(new Boolean

(),ViewChanged));

 

private ObservableCollection<ExposureItem

> _GroupedItems;

public ObservableCollection<ExposureItem

> GroupedItems

{

get { return

_GroupedItems; }

set

{

if (_GroupedItems != value

)

{

_GroupedItems =

value

;

OnPropertyChanged(

"GroupedItems"

);

}

}

}

private bool

_LoadingData;

public bool

LoadingData

{

get { return

_LoadingData; }

set

{

if (_LoadingData != value

)

{

_LoadingData =

value

;

OnPropertyChanged(

"LoadingData"

);

}

}

}

public decimal MinValue { get; set

; }

public decimal MaxValue { get; set

; }

public XamDataGrid AccountGrid { get { return

Grid1; } }

private bool

IsDirty;

public

ExposureMatrixAccountGrid()

{

InitializeComponent();

SummaryCalculator.Register(MarketValueSummaryCalculator

.Calculator);

IsDirty =

true

;

IsVisibleChanged +=

new DependencyPropertyChangedEventHandler

(ExposureMatrixAccountGrid_IsVisibleChanged);

}

 

void ExposureMatrixAccountGrid_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs

e)

{

RebuildGrid();

}

 

public static void ViewChanged(DependencyObject sender, DependencyPropertyChangedEventArgs

e)

{

ExposureMatrixAccountGrid control = sender as ExposureMatrixAccountGrid

;

control.IsDirty =

true

;

control.RebuildGrid();

}

 

public static void DataChanged(DependencyObject sender, DependencyPropertyChangedEventArgs

e)

{

ExposureMatrixAccountGrid control = sender as ExposureMatrixAccountGrid

;

control.IsDirty =

true

;

control.RebuildGrid();

}

 

private void

RebuildGrid()

{

if (!IsDirty || this.Visibility != Visibility

.Visible)

return

;

LoadingData =

true

;

Grid1.DataSource =

null

;

Grid1.DataSource =

new ObservableCollection<ExposureItem

>();

Grid1.DataSource = GroupedItems;

 

 

Task

.Factory.StartNew(() =>

{

// Group items by (not) Coupon

try

{

Dispatcher.BeginInvoke((

Action)delegate

()

{

MinValue = Items.Any() ? Items.Min(x => x.Qty) : 0;

MaxValue = Items.Any() ? Items.Max(x => x.Qty) : 0;

GroupedItems =

new ObservableCollection<ExposureItem

>(

Items

.GroupBy(x =>

new

{ x.AcctNo, x.Collateral, x.DeliveryDate, x.AcctMarketValue, x.PM_Name, x.Type })

.Select(x =>

new

ExposureItem

{

AcctNo = x.Key.AcctNo,

Collateral = x.Key.Collateral,

DeliveryDate = x.Key.DeliveryDate,

AcctMarketValue = x.Key.AcctMarketValue,

PM_Name = x.Key.PM_Name,

Type = x.Key.Type

})

.OrderBy(x => x.AcctNo));

IsDirty =

false

;

});

}

finally

{

LoadingData =

false

;

}

}).ContinueWith(x =>

{

if (x.Exception != null

)

throw new Exception("See Inner Exception"

, x.Exception);

},

TaskScheduler

.FromCurrentSynchronizationContext());

}

 

///

<summary>

///

Build out coupon coulums in datagrid. Add a column for total and for every distinct coupon.

///

</summary>

///

<param name="sender"></param>

///

<param name="e"></param>

private void Grid1_FieldLayoutInitialized(object sender, Infragistics.Windows.DataPresenter.Events.FieldLayoutInitializedEventArgs

e)

{

Style AmountStyle = (Style)TryFindResource(IsQuantityView ? "AmountStyle" : "Percent3Style"

);

string stringFormat = "{0:" + ((Setter)AmountStyle.Setters[0]).Value.ToString() + "}"

;

SummaryCalculator

calculator;

List<decimal

> coupons = Items.Select(x => x.Coupon).OrderBy(x => x).Distinct().ToList();

coupons.Insert(0, -1m);

// Create a total column. Use minus one as a coupon to identify the total column

foreach (decimal coupon in

coupons)

{

string columnName = Guid.NewGuid().ToString();

// Generate a bogus field name so the summary calculator knows what to total

if

(IsQuantityView)

calculator =

new SumSummaryCalculator

();

else

calculator =

new PctMarketValueSummaryCalculator

();

UnboundField unboundField = new

UnboundField

{

Name = columnName,

Label = coupon == -1 ?

"Total" : coupon.ToString("#.###") + "%"

,

DataType =

typeof(decimal

),

Settings =

new FieldSettings

{ EditorStyle = AmountStyle },

Width =

new FieldLength

(80),

};

MultiBinding mb = new MultiBinding { Converter = new CouponColumnConverter

() };

mb.Bindings.Add(

new Binding());

// The row being bound

mb.Bindings.Add(

new Binding { Source = coupon });

// The coupon that identifies the column.

mb.Bindings.Add(

new Binding { Source = Items });

// Lookup list to see if an entry for coupon for passed row exists

mb.Bindings.Add(

new Binding { Source = IsQuantityView });

// true to display qty, false to display pct mkt value.

mb.Bindings.Add(

new Binding

{ Source = unboundField });

mb.Bindings.Add(

new Binding

{ Source = MinValue });

mb.Bindings.Add(

new Binding

{ Source = MaxValue });

unboundField.Binding = mb;

e.FieldLayout.Fields.Add(unboundField);

Grid1.FieldLayouts[0].SummaryDefinitions.Add(

new SummaryDefinition

{ Calculator = calculator, StringFormat = stringFormat, SourceFieldName = columnName });

}

}

private void Grid1_InitializeRecord(object sender, InitializeRecordEventArgs

e)

{

//e.Record.DataPresenter.Background = Brushes.Yellow;

//var zz = e.Record.FieldLayout.Fields[0].GetValue(CellValuePresenter.

}

private void Grid1_Loaded(object sender, RoutedEventArgs

e)

{

//int rowCount = Grid1.Records.Count;

//if (rowCount == 0)

// return;

//int cellCount = ((DataRecord)Grid1.Records[0]).Cells.Count;

//for (int row = 0; row < rowCount; row++)

// for (int cell = 6; cell < cellCount; cell++)

// CellValuePresenter.FromCell((Grid1.Records[row] as DataRecord).Cells[cell]).Background = Brushes.Yellow;

}

}

 

public class CouponColumnConverter :

IMultiValueConverter

{

public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo

culture)

{

ExposureItem boundItem = (ExposureItem

)value[0];

decimal coupon = System.Convert.ToDecimal(value[1]);

// coupon will be minus one if this is the totals column

IList<ExposureItem> list = (IList<ExposureItem

>)value[2];

bool isQuantityView = (bool

)value[3];

UnboundField field = (UnboundField

)value[4];

decimal minValue = (decimal

)value[5];

decimal maxValue = (decimal

)value[6];

decimal

result = 0;

 

IEnumerable<ExposureItem

> items = list.Where(x =>

x.AcctNo == boundItem.AcctNo

&& x.Collateral == boundItem.Collateral

&& x.DeliveryDate == boundItem.DeliveryDate

&& x.PM_Name == boundItem.PM_Name

&& x.Type == boundItem.Type

&& (x.Coupon == coupon || coupon == -1));

// Sum all coupons if this is the totals column

if (items == null

)

return Binding

.DoNothing;

else

{

if

(isQuantityView)

result = items.Sum(x => x.Qty);

else

{

if

(items.Any() && items.First().AcctMarketValue != 0)

result = items.Sum(x => x.MktValue) / items.First().AcctMarketValue;

}

}

//MultiBinding heatMap = new MultiBinding { Converter = new Converters.HeatMapConverter() };

//heatMap.Bindings.Add(new Binding { Source = result });

//heatMap.Bindings.Add(new Binding { Source = minValue });

//heatMap.Bindings.Add(new Binding { Source = maxValue });

//Style backgroundStyle = new Style();

//backgroundStyle.Setters.Add(new Setter { Property = System.Windows.Controls.Control.BackgroundProperty, Value = heatMap });

//field.Settings.CellValuePresenterStyle = backgroundStyle;

return

result;

}

public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo

culture)

{

throw new NotImplementedException

();

}

}

///

<summary>

///

Accounts may be repeated on multiple rows becuse each security type is on its own row.

///

This class ensures the account market value for each account is counted once only.

///

</summary>

public class MarketValueSummaryCalculator :

SumSummaryCalculator

{

static MarketValueSummaryCalculator

_Calculator;

public static MarketValueSummaryCalculator

Calculator

{

get

{

if (_Calculator == null

)

_Calculator =

new MarketValueSummaryCalculator

();

return

_Calculator;

}

}

private List<decimal

> SummedAccounts;

public

MarketValueSummaryCalculator()

{

SummedAccounts =

new List<decimal

>();

}

public override void BeginCalculation(SummaryResult

summaryResult)

{

SummedAccounts.Clear();

base

.BeginCalculation(summaryResult);

}

public override void Aggregate(object dataValue, SummaryResult summaryResult, Record

record)

{

ExposureItem item = (ExposureItem)((DataRecord

)record).DataItem;

if

(SummedAccounts.Where(x => x == item.AcctNo).Any())

return

;

SummedAccounts.Add(item.AcctNo);

base

.Aggregate(dataValue, summaryResult, record);

}

public override string

Name

{

get { return "MarketValueSummaryCalculator"

; }

}

}

///

<summary>

///

Summs MarketValue / AccountMarketValue

///

</summary>

public class PctMarketValueSummaryCalculator :

SumSummaryCalculator

{

static PctMarketValueSummaryCalculator

_Calculator;

public static PctMarketValueSummaryCalculator

Calculator

{

get

{

if (_Calculator == null

)

_Calculator =

new PctMarketValueSummaryCalculator

();

return

_Calculator;

}

}

private List<decimal

> SummedAccounts;

private decimal

MktValue;

private decimal

AcctMktValue;

public

PctMarketValueSummaryCalculator()

{

SummedAccounts =

new List<decimal

>();

}

 

public override void Aggregate(object dataValue, SummaryResult summaryResult, Record

record)

{

ExposureItem item = (ExposureItem)((DataRecord

)record).DataItem;

MktValue += (

Convert

.ToDecimal(dataValue) * item.AcctMarketValue);

if

(!SummedAccounts.Where(x => x == item.AcctNo).Any())

{

SummedAccounts.Add(item.AcctNo);

AcctMktValue += item.AcctMarketValue;

}

}

public override object EndCalculation(SummaryResult

summaryResult)

{

return

AcctMktValue == 0 ? 0 : MktValue / AcctMktValue;

}

public override string

Name

{

get { return "PctMarketValueSummaryCalculator"

; }

}

}

}

 

<

common:BaseUserControl x:Class

="Poolman.Controls.ExposureMatrixAccountGrid"

xmlns

="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x

="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:igDP

="http://infragistics.com/DataPresenter"

xmlns:xamSpin

="clr-namespace:xamlSpinnersWPF;assembly=BlackSpike.XamSpinner"

xmlns:common="clr-namespace:Poolman.Common"

xmlns:views

="clr-namespace:Poolman.Views"

xmlns:controls

="clr-namespace:Poolman.Controls"

mc:Ignorable="d"

d:DesignHeight="300" d:DesignWidth

="300">

<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type common:BaseUserControl

}}}" >

<igDP:XamDataGrid x:Name

="Grid1"

Grid.Row

="0"

FieldLayoutInitialized

="Grid1_FieldLayoutInitialized"

InitializeRecord

="Grid1_InitializeRecord"

Loaded

="Grid1_Loaded"

ScrollViewer.HorizontalScrollBarVisibility

="Auto"

DataSource="{Binding GroupedItems

}"

GroupByAreaLocation

="None">

<igDP:XamDataGrid.FieldSettings

>

<igDP:FieldSettings AllowEdit="False"

SummaryDisplayArea

="BottomFixed"

AllowRecordFiltering

="True"

FilterLabelIconDropDownType

="MultiSelectExcelStyle"

CellClickAction

="SelectRecord"/>

</igDP:XamDataGrid.FieldSettings

>

<igDP:XamDataGrid.FieldLayoutSettings

>

<igDP:FieldLayoutSettings

AllowDelete

="False"

AllowAddNew

="False"

AllowFieldMoving

="WithinLogicalRow"

AutoGenerateFields

="False"

HighlightAlternateRecords

="True"

RecordSelectorLocation

="None"

FilterUIType

="LabelIcons"/>

</igDP:XamDataGrid.FieldLayoutSettings

>

<igDP:XamDataGrid.FieldLayouts

>

<igDP:FieldLayout

>

<igDP:FieldLayout.SortedFields

>

<igDP:FieldSortDescription

Direction="Ascending"

FieldName

="ACCT_NO"/>

</igDP:FieldLayout.SortedFields

>

<igDP:FieldLayout.Fields

>

<igDP:Field Name="AcctNo" Label="Acct" FixedLocation="FixedToNearEdge" Width

="60">

<igDP:Field.Settings

>

<igDP:FieldSettings EditorStyle="{StaticResource PoolmanDecimalStyle

}"/>

</igDP:Field.Settings

>

</igDP:Field

>

<igDP:Field Name="PM_Name" Label="PM" FixedLocation

="FixedToNearEdge" />

<igDP:Field Name="Collateral" Label="Coll." Width="60" FixedLocation

="FixedToNearEdge"/>

<igDP:Field Name="Type" Label="Type" Width="60" FixedLocation

="FixedToNearEdge"/>

<igDP:Field Name="AcctMarketValue" Label

="MV">

<igDP:Field.Settings

>

<igDP:FieldSettings EditorStyle="{StaticResource AmountStyle

}"/>

</igDP:Field.Settings

>

</igDP:Field

>

<igDP:Field Name="DeliveryDate" Label

="Dlvry Date">

<igDP:Field.Settings

>

<igDP:FieldSettings EditorStyle="{StaticResource AmountStyle

}"/>

</igDP:Field.Settings

>

</igDP:Field

>

 

</igDP:FieldLayout.Fields

>

<igDP:FieldLayout.SummaryDefinitions

>

<igDP:SummaryDefinition SourceFieldName="AcctMarketValue"

Calculator="{x:Static controls:MarketValueSummaryCalculator

.Calculator}"

StringFormat

="{}{0:#,#;(#,#)}" />

<igDP:SummaryDefinition SourceFieldName="PctMktValue"

Calculator

="Avg"

StringFormat

="{}{0:#,#;(#,#)}"/>

</igDP:FieldLayout.SummaryDefinitions

>

</igDP:FieldLayout

>

</igDP:XamDataGrid.FieldLayouts

>

</igDP:XamDataGrid

>

<Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="216" Width="216" Grid.Row

="0"

Visibility="{Binding Path=LoadingData, Converter={StaticResource BoolToVisConverter

}}">

<xamSpin:ucSpinnerApple

>

<xamSpin:ucSpinnerApple.RenderTransform

>

<ScaleTransform ScaleX="9" ScaleY

="9"/>

</xamSpin:ucSpinnerApple.RenderTransform

>

</xamSpin:ucSpinnerApple

>

</Canvas

>

</Grid

>

</

common:BaseUserControl

>

Parents Reply Children
No Data