Hi,
I have a RadGridView bind to a datatable and sort by Name column. My problem is after I modify the Name column, the RadGridView performs a 'auto sort' and the current selected row is deselected and the SelectedItem is Nothing.
How can I preserve the selected row after the 'auto sort'?
Thanks,
Chris
<
telerik:RadGridView
DockPanel.Dock
=
"Top"
x:Name
=
"gv"
SelectionMode
=
"Single"
RowHeight
=
"30"
IsSynchronizedWithCurrentItem
=
"True"
AutoGenerateColumns
=
"False"
ShowGroupPanel
=
"False"
>
<
telerik:RadGridView.Columns
>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Path=Name}"
Header
=
"Name"
UniqueName
=
"Name"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Path=PhoneNumber}"
Header
=
"Phone Number"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Path=City}"
Header
=
"City"
/>
<
telerik:GridViewDataColumn
DataMemberBinding
=
"{Binding Path=State}"
Header
=
"State"
/> </
telerik:RadGridView.Columns
>
<
telerik:RadGridView.SortDescriptors
>
<
telerik:ColumnSortDescriptor
Column
=
"{Binding Columns[\Name\], ElementName=gv}"
SortDirection
=
"Ascending"
/>
</
telerik:RadGridView.SortDescriptors
>
</
telerik:RadGridView
>
#define DISPACTTIMER #define THREADTIMER
<
Window
x:Class
=
"WpfRadMap.MainWindow"
Title
=
"MainWindow"
Height
=
"1080"
Width
=
"1900"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
ResizeMode
=
"NoResize"
Activated
=
"Window_Activated"
>
<
Grid
>
<
telerik:RadMap
Panel.ZIndex
=
"1"
HorizontalAlignment
=
"Stretch"
Name
=
"radMap1"
VerticalAlignment
=
"Stretch"
Center
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Mode=TwoWay, Path=MapLocation}"
ZoomChanged
=
"radMap1_ZoomChanged"
/>
<
Canvas
Panel.ZIndex
=
"2"
x:Name
=
"gizmoPanel"
Visibility
=
"Visible"
HorizontalAlignment
=
"Stretch"
VerticalAlignment
=
"Stretch"
RenderTransformOrigin
=
"0.5,0.5"
>
<
Canvas.RenderTransform
>
<
RotateTransform
x:Name
=
"GizmoRotate"
Angle
=
"0"
/>
</
Canvas.RenderTransform
>
<
Line
Stroke
=
"Red"
StrokeThickness
=
"3"
ClipToBounds
=
"True"
X1
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoX1}"
X2
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoX1}"
Y1
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoY1}"
Y2
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoY2}"
Visibility
=
"Visible"
IsHitTestVisible
=
"False"
>
<
Line.Effect
>
<
DropShadowEffect
BlurRadius
=
"5"
ShadowDepth
=
"0"
/>
</
Line.Effect
>
</
Line
>
<!-- Small Line 1 -->
<
Line
Stroke
=
"Red"
StrokeThickness
=
"3"
ClipToBounds
=
"True"
X1
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoX1}"
X2
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoX2}"
Y1
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoY2}"
Y2
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoY3}"
Visibility
=
"Visible"
IsHitTestVisible
=
"False"
>
<
Line.Effect
>
<
DropShadowEffect
BlurRadius
=
"5"
ShadowDepth
=
"0"
/>
</
Line.Effect
>
</
Line
>
<!-- Small Line 2 -->
<
Line
Stroke
=
"Red"
StrokeThickness
=
"3"
ClipToBounds
=
"True"
X1
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoX1}"
X2
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoX3}"
Y1
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoY2}"
Y2
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=GizmoY3}"
Visibility
=
"Visible"
IsHitTestVisible
=
"False"
>
<
Line.Effect
>
<
DropShadowEffect
BlurRadius
=
"5"
ShadowDepth
=
"0"
/>
</
Line.Effect
>
</
Line
>
</
Canvas
>
<
Button
Panel.ZIndex
=
"3"
Content
=
"Rotate Clockwise"
Height
=
"39"
Name
=
"button1"
Width
=
"99"
Click
=
"button1_Click"
Margin
=
"1690,12,39,980"
/>
<
Button
Panel.ZIndex
=
"3"
Content
=
"Rotate AntiClockwise"
Height
=
"39"
Name
=
"button2"
Width
=
"119"
Click
=
"button2_Click"
Margin
=
"1680,57,28,935"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"1670,100, 0,910"
Content
=
"[W] to move along arrow"
Height
=
"28"
Name
=
"label1"
Width
=
"180"
FontWeight
=
"Bold"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"1670,120, 0,890"
Content
=
"[S] to move opposite to arrow"
Height
=
"28"
Name
=
"label2"
Width
=
"180"
FontWeight
=
"Bold"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"1670,140, 0,870"
Content
=
"[A] to move left of arrow"
Height
=
"28"
Name
=
"label3"
Width
=
"180"
FontWeight
=
"Bold"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"1670,160, 0,850"
Content
=
"[D] to move right of arrow"
Height
=
"28"
Name
=
"label4"
Width
=
"180"
FontWeight
=
"Bold"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"0,10, 1670,980"
Content
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=FastestTime}"
Height
=
"28"
Name
=
"lblMinSpeed"
Width
=
"180"
FontWeight
=
"Bold"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"0,40, 1670,950"
Content
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=SlowestTime}"
Height
=
"28"
Name
=
"lblMaxSpeed"
Width
=
"180"
FontWeight
=
"Bold"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"0,70, 1670,920"
Content
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=AverageTime}"
Height
=
"28"
Name
=
"lblAvgSpeed"
Width
=
"180"
FontWeight
=
"Bold"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"0,110, 1670,880"
Content
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=FastestUpdateTime}"
Height
=
"28"
Name
=
"lblMinUpdate"
Width
=
"180"
FontWeight
=
"Bold"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"0,140, 1670,850"
Content
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=SlowestUpdateTime}"
Height
=
"28"
Name
=
"lblMaxUpdate"
Width
=
"180"
FontWeight
=
"Bold"
/>
<
Label
Panel.ZIndex
=
"3"
Margin
=
"0,170, 1670,820"
Content
=
"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=AverageUpdateTime}"
Height
=
"28"
Name
=
"lblAvgUpdate"
Width
=
"180"
FontWeight
=
"Bold"
/>
</
Grid
>
</
Window
>
#define QUERY_PERFORMANCE
//#define DISPACTTIMER
//#define THREADTIMER
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.Windows.Threading;
using
System.Timers;
using
System.ComponentModel;
namespace
WpfRadMap
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public
partial
class
MainWindow : Window, INotifyPropertyChanged
{
Telerik.Windows.Controls.Map.Location m_location;
double
width = 1900.0;
double
height = 1080.0;
private
double
gizmoX1;
private
double
gizmoX2;
private
double
gizmoX3;
private
double
gizmoY1;
private
double
gizmoY2;
private
double
gizmoY3;
private
RotateTransform longLatRotate;
private
double
framesPerSecond = 60.0;
#if DISPACTTIMER
DispatcherTimer m_updateTimer;
#elif THREADTIMER
Timer m_updateTimer;
#endif
public
MainWindow()
{
gizmoX1 = width * 0.5;
gizmoX2 = width * 0.485;
gizmoX3 = width * 0.515;
gizmoY1 = height * 0.5;
gizmoY2 = height * 0.45;
gizmoY3 = height * 0.475;
longLatRotate =
new
RotateTransform();
longLatRotate.Angle = 0.0;
m_location =
new
Telerik.Windows.Controls.Map.Location();
InitializeComponent();
const
string
bingKey =
""
;
if
(bingKey.Length > 0)
{
Telerik.Windows.Controls.Map.BingMapProvider bingProvider =
new
Telerik.Windows.Controls.Map.BingMapProvider(Telerik.Windows.Controls.Map.MapMode.Aerial,
true
, bingKey);
bingProvider.IsTileCachingEnabled =
true
;
bingProvider.IsLabelVisible =
true
;
radMap1.Provider = bingProvider;
SetLabelsFontColor(Brushes.White);
}
else
{
Telerik.Windows.Controls.Map.OpenStreetMapProvider openProvider =
new
Telerik.Windows.Controls.Map.OpenStreetMapProvider();
openProvider.IsTileCachingEnabled =
true
;
radMap1.Provider = openProvider;
}
radMap1.ZoomLevel = 19;
m_location.Latitude = 48.856941702106354;
m_location.Longitude = 2.3383069038354383;
MapLocation = m_location;
#if DISPACTTIMER
m_updateTimer =
new
DispatcherTimer();
m_updateTimer.Tick +=
new
EventHandler(m_updateTimer_Tick);
m_updateTimer.Interval = TimeSpan.FromSeconds(1.0/framesPerSecond);
#elif THREADTIMER
m_updateTimer =
new
Timer();
m_updateTimer.Elapsed +=
new
ElapsedEventHandler(m_updateTimer_Tick);
m_updateTimer.Interval = (1.0 / framesPerSecond) * 100;
m_updateTimer.Enabled =
false
;
#else
System.Windows.Interop.ComponentDispatcher.ThreadIdle +=
new
System.EventHandler(ComponentDispatcher_ThreadIdle);
#endif
profileTimer = System.Diagnostics.Stopwatch.StartNew();
}
public
Telerik.Windows.Controls.Map.Location MapLocation
{
get
{
return
m_location; }
set
{ m_location = value; RaisePropertyChanged(
"MapLocation"
);
}
}
double
m_mapHeight = 0.0001;
public
double
MapHeight
{
get
{
return
m_mapHeight;}
set
{m_mapHeight = value; RaisePropertyChanged(
"MapHeight"
);}
}
private
void
radMap1_ZoomChanged(
object
sender, EventArgs e)
{
MapHeight = radMap1.GeographicalBounds.Height;
}
readonly
Queue<
long
> m_frameTicks =
new
Queue<
long
>();
long
m_slowest =
long
.MinValue;
long
m_fastest =
long
.MaxValue;
long
m_avg = 0;
public
string
AverageTime
{
get
{
return
"Avg: "
+ m_avg +
"us"
; }
}
public
string
SlowestTime
{
get
{
return
"Slowest: "
+ m_slowest +
"us"
; }
}
public
string
FastestTime
{
get
{
return
"Fastest: "
+ m_fastest +
"us"
; }
}
readonly
Queue<
long
> m_frameUpdateTicks =
new
Queue<
long
>();
long
m_slowestUpdate =
long
.MinValue;
long
m_fastestUpdate =
long
.MaxValue;
long
m_avgUpdate = 0;
System.Diagnostics.Stopwatch profileTimer;
public
string
AverageUpdateTime
{
get
{
return
"AvgUpdate: "
+ m_avgUpdate +
"ms"
; }
}
public
string
SlowestUpdateTime
{
get
{
return
"SlowestUpdate: "
+ m_slowestUpdate +
"ms"
; }
}
public
string
FastestUpdateTime
{
get
{
return
"FastestUpdate: "
+ m_fastestUpdate +
"ms"
; }
}
protected
void
CalculatePerformance(
long
a_currentTick, Queue<
long
> a_avgTicks,
ref
long
a_slowestTick,
ref
long
a_fastestTick,
ref
long
a_avgTick)
{
a_avgTicks.Enqueue(a_currentTick);
if
(a_avgTicks.Count > 60)
{
a_avgTicks.Dequeue();
}
long
slowest = a_currentTick;
long
fastest = a_currentTick;
long
total = 0;
foreach
(
long
time
in
a_avgTicks)
{
total += time;
slowest = Math.Max(slowest, time);
fastest = Math.Min(fastest, time);
}
a_avgTick = total / a_avgTicks.Count;
a_slowestTick = slowest;
a_fastestTick = fastest;
}
#if DISPACTTIMER
void
m_updateTimer_Tick(
object
sender, EventArgs e)
#elif THREADTIMER
void
m_updateTimer_Tick(
object
sender, ElapsedEventArgs e)
#else
void
ComponentDispatcher_ThreadIdle(
object
sender, EventArgs e)
#endif
{
long
elapsedTime = profileTimer.ElapsedTicks;
long
elapsedMilliSeconds = System.Convert.ToInt64((System.Convert.ToDouble(elapsedTime) / System.Convert.ToDouble(System.Diagnostics.Stopwatch.Frequency)) * 1000);
// if (elapsedMilliSeconds < (1.0/framesPerSecond)*1000)
// {
// return;
// }
CalculatePerformance(elapsedMilliSeconds, m_frameUpdateTicks,
ref
m_slowestUpdate,
ref
m_fastestUpdate,
ref
m_avgUpdate);
RaisePropertyChanged(
"SlowestUpdateTime"
);
RaisePropertyChanged(
"FastestUpdateTime"
);
RaisePropertyChanged(
"AverageUpdateTime"
);
profileTimer.Restart();
double
tearRepair = 1.0;
if
(elapsedMilliSeconds > 0)
{
tearRepair = elapsedMilliSeconds / framesPerSecond;
}
double
speed = 2.0;
double
latitude = m_location.Latitude;
double
longitude = m_location.Longitude;
#if THREADTIMER
Point stepDir =
new
Point(0.0, (MapHeight/(speed * framesPerSecond))*tearRepair);
Point dir = stepDir;
//longLatRotate.Transform(stepDir);
latitude += dir.Y;
longitude -= dir.X;
#else
#if DISPACTTIMER
Point stepDir =
new
Point(0.0, (MapHeight/(speed * framesPerSecond))*tearRepair);
#else
Point stepDir =
new
Point(0.0, (MapHeight / (speed * framesPerSecond)) * tearRepair);
#endif
Point dir = longLatRotate.Transform(stepDir);
if
((Keyboard.GetKeyStates(Key.W) & KeyStates.Down) > 0)
{
latitude += dir.Y;
longitude -= dir.X;
}
if
((Keyboard.GetKeyStates(Key.S) & KeyStates.Down) > 0)
{
latitude -= dir.Y;
longitude += dir.X;
}
if
((Keyboard.GetKeyStates(Key.A) & KeyStates.Down) > 0)
{
latitude -= dir.X;
longitude -= dir.Y;
}
if
((Keyboard.GetKeyStates(Key.D) & KeyStates.Down) > 0)
{
latitude += dir.X;
longitude += dir.Y;
}
#endif
while
(latitude>360)
{
latitude-=360;
}
while
(latitude < 0)
{
latitude += 360;
}
while
(longitude > 360)
{
longitude -= 360;
}
while
(longitude < 0)
{
longitude += 360;
}
m_location.Latitude = latitude;
m_location.Longitude = longitude;
RaisePropertyChanged(
"MapLocation"
);
elapsedTime = profileTimer.ElapsedTicks;
long
elapsedMicroSeconds = System.Convert.ToInt64((System.Convert.ToDouble(elapsedTime) / System.Convert.ToDouble(System.Diagnostics.Stopwatch.Frequency))*1000000);
CalculatePerformance(elapsedMicroSeconds, m_frameTicks,
ref
m_slowest,
ref
m_fastest,
ref
m_avg);
RaisePropertyChanged(
"SlowestTime"
);
RaisePropertyChanged(
"FastestTime"
);
RaisePropertyChanged(
"AverageTime"
);
}
public
double
GizmoX1
{
get
{
return
gizmoX1; }
set
{ gizmoX1 = value; }
}
public
double
GizmoX2
{
get
{
return
gizmoX2; }
set
{ gizmoX2 = value; }
}
public
double
GizmoX3
{
get
{
return
gizmoX3; }
set
{ gizmoX3 = value; }
}
public
double
GizmoY1
{
get
{
return
gizmoY1; }
set
{ gizmoY1 = value; }
}
public
double
GizmoY2
{
get
{
return
gizmoY2; }
set
{ gizmoY2 = value; }
}
public
double
GizmoY3
{
get
{
return
gizmoY3; }
set
{ gizmoY3 = value; }
}
private
void
button2_Click(
object
sender, RoutedEventArgs e)
{
longLatRotate.Angle = GizmoRotate.Angle = (GizmoRotate.Angle + 15) % 360;
}
private
void
button1_Click(
object
sender, RoutedEventArgs e)
{
longLatRotate.Angle = GizmoRotate.Angle = (GizmoRotate.Angle - 15);
if
(GizmoRotate.Angle == 0)
{
longLatRotate.Angle = GizmoRotate.Angle = 360;
}
}
void
SetLabelsFontColor(Brush a_color)
{
lblMinUpdate.Foreground = a_color;
lblMaxUpdate.Foreground = a_color;
lblAvgUpdate.Foreground = a_color;
lblMinSpeed.Foreground = a_color;
lblMaxSpeed.Foreground = a_color;
lblAvgSpeed.Foreground = a_color;
label1.Foreground = a_color;
label2.Foreground = a_color;
label3.Foreground = a_color;
label4.Foreground = a_color;
}
/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
protected
void
RaisePropertyChanged(
string
propertyName)
{
this
.VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler =
this
.PropertyChanged;
if
(handler !=
null
)
{
PropertyChangedEventArgs e =
new
PropertyChangedEventArgs(propertyName);
handler(
this
, e);
}
}
/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
public
void
VerifyPropertyName(
string
propertyName)
{
// If you raise PropertyChanged and do not specify a property name,
// all properties on the object are considered to be changed by the binding system.
if
(String.IsNullOrEmpty(propertyName))
{
return
;
}
// Verify that the property name matches a real,
// public, instance property on this object.
if
(TypeDescriptor.GetProperties(
this
)[propertyName] ==
null
)
{
string
msg =
"Invalid property name: "
+ propertyName;
if
(
this
.ThrowOnInvalidPropertyName)
{
throw
new
ArgumentException(msg);
}
}
}
/// <summary>
/// Returns whether an exception is thrown, or if a Debug.Fail() is used
/// when an invalid property name is passed to the VerifyPropertyName method.
/// The default value is false, but subclasses used by unit tests might
/// override this property's getter to return true.
/// </summary>
protected
virtual
bool
ThrowOnInvalidPropertyName {
get
;
private
set
; }
/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public
event
PropertyChangedEventHandler PropertyChanged;
private
void
Window_Activated(
object
sender, EventArgs e)
{
MapHeight = radMap1.GeographicalBounds.Height;
#if DISPACTTIMER
m_updateTimer.Start();
#elif THREADTIMER
m_updateTimer.Enabled =
true
;
#endif
}
}
}
Versjon: 2012.2.101.15, OS: Microsoft Windows NT 5.2.3790 Service Pack 2 64-bits: False
Exception: Not enough storage is available to process this command
Telerik.Windows.Controls.InternalWindow.Standard.NativeMethods
CreateRoundRectRgn
Source: Telerik.Windows.Controls
Target: IntPtr CreateRoundRectRgn(Int32, Int32, Int32, Int32, Int32, Int32)
Stacktrace: at Telerik.Windows.Controls.InternalWindow.Standard.NativeMethods.CreateRoundRectRgn(Int32 nLeftRect, Int32 nTopRect, Int32 nRightRect, Int32 nBottomRect, Int32 nWidthEllipse, Int32 nHeightEllipse)
at Telerik.Windows.Controls.InternalWindow.ChromelessWindowHelper.RoundNonTransparentWindowCorners(IntPtr hwnd)
at Telerik.Windows.Controls.InternalWindow.ChromelessWindowHelper.HandlePositionChanged(IntPtr hwnd, IntPtr wParam, IntPtr lParam, Boolean& handled)
at Telerik.Windows.Controls.InternalWindow.ChromelessWindowHelper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
Any suggestions on what is going on here?
Best regards
Arnstein