Some weeks ago I implemented a CustomGridViewToggleRowDetailsColumn class. Basically, my data model has objects called Reads which can have zero or more Alarms associated with them. I've written code which populates an array in the Read view model object with all of the Alarms that are associated with that particular Read. The class hides the toggle button for the row details if the item in the row doesn't have any rows in that array. There's another boolean property on the Read view model object called HasAlarms which is true if the Alarms array isn't empty.
In order to improve performance, I need to rework the data access code so it no longer retrieves all of the Alarms assocated with a Read at the time it retrieves the Reads that match the search criteria. Instead, I am setting the HasAlarms property to true if there are any Alarms for that Read and leaving the array null. I want the row details toggle button to be hidden if HasAlarms is false (easily done with existing code). Then, when the user clicks on the toggle button, I want to check to see if the Alarms for that Read were retrieved yet, and if not, go get them.
The problem is that I'm getting an error when the Xaml for the RadGridView is being parsed because it doesn't like something about my code. The error I'm getting is:
System.Windows.Markup.XamlParseException occurred
Message='Failed to create a 'Click' from the text 'ExpandAlarms_Click'.' Line number '416' and line position '9'.
Source=PresentationFramework
LineNumber=416
LinePosition=9
StackTrace:
at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
at CarSystem.CustomControls.Searcher.InitializeComponent() in d:\ElsagTFS\EOC4\Client UI\CustomControls\Searcher.xaml:line 1
at CarSystem.CustomControls.Searcher..ctor() in D:\ElsagTFS\EOC4\Client UI\CustomControls\Searcher.xaml.cs:line 431
InnerException: System.ArgumentException
Message=Error binding to target method.
Source=mscorlib
StackTrace:
at System.Delegate.CreateDelegate(Type type, Object target, String method, Boolean ignoreCase, Boolean throwOnBindFailure)
at System.Xaml.Schema.SafeReflectionInvoker.CreateDelegate(Type delegateType, Object target, String methodName)
at System.Xaml.EventConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateObjectWithTypeConverter(ServiceProviderContext serviceContext, XamlValueConverter`1 ts, Object value)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateFromValue(ServiceProviderContext serviceContext, XamlValueConverter`1 ts, Object value, XamlMember property)
at MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.CreateFromValue(ServiceProviderContext serviceContext, XamlValueConverter`1 ts, Object value, XamlMember property)
at System.Xaml.XamlObjectWriter.Logic_CreateFromValue(ObjectWriterContext ctx, XamlValueConverter`1 typeConverter, Object value, XamlMember property, String targetName, IAddLineInfo lineInfo)
InnerException:
Here's the code for my class. Please help me fix this problem.
Tony
In order to improve performance, I need to rework the data access code so it no longer retrieves all of the Alarms assocated with a Read at the time it retrieves the Reads that match the search criteria. Instead, I am setting the HasAlarms property to true if there are any Alarms for that Read and leaving the array null. I want the row details toggle button to be hidden if HasAlarms is false (easily done with existing code). Then, when the user clicks on the toggle button, I want to check to see if the Alarms for that Read were retrieved yet, and if not, go get them.
The problem is that I'm getting an error when the Xaml for the RadGridView is being parsed because it doesn't like something about my code. The error I'm getting is:
System.Windows.Markup.XamlParseException occurred
Message='Failed to create a 'Click' from the text 'ExpandAlarms_Click'.' Line number '416' and line position '9'.
Source=PresentationFramework
LineNumber=416
LinePosition=9
StackTrace:
at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
at CarSystem.CustomControls.Searcher.InitializeComponent() in d:\ElsagTFS\EOC4\Client UI\CustomControls\Searcher.xaml:line 1
at CarSystem.CustomControls.Searcher..ctor() in D:\ElsagTFS\EOC4\Client UI\CustomControls\Searcher.xaml.cs:line 431
InnerException: System.ArgumentException
Message=Error binding to target method.
Source=mscorlib
StackTrace:
at System.Delegate.CreateDelegate(Type type, Object target, String method, Boolean ignoreCase, Boolean throwOnBindFailure)
at System.Xaml.Schema.SafeReflectionInvoker.CreateDelegate(Type delegateType, Object target, String methodName)
at System.Xaml.EventConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateObjectWithTypeConverter(ServiceProviderContext serviceContext, XamlValueConverter`1 ts, Object value)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateFromValue(ServiceProviderContext serviceContext, XamlValueConverter`1 ts, Object value, XamlMember property)
at MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.CreateFromValue(ServiceProviderContext serviceContext, XamlValueConverter`1 ts, Object value, XamlMember property)
at System.Xaml.XamlObjectWriter.Logic_CreateFromValue(ObjectWriterContext ctx, XamlValueConverter`1 typeConverter, Object value, XamlMember property, String targetName, IAddLineInfo lineInfo)
InnerException:
Here's the code for my class. Please help me fix this problem.
class
CustomGridViewToggleRowDetailsColumn : GridViewBoundColumnBase {
public
static
RoutedEvent ClickEvent =
EventManager.RegisterRoutedEvent(
"Click"
, RoutingStrategy.Bubble,
typeof
( ToggleRowDetailsColumnRoutedEventHandler ),
typeof
( CustomGridViewToggleRowDetailsColumn ) );
public
GridViewCell Cell {
get
;
set
; }
public
event
RoutedEventHandler Click {
add { AddHandler( ClickEvent, value ); }
remove { RemoveHandler( ClickEvent, value ); }
}
public
override
object
Header {
get
{
return
null
; }
set
{
base
.Header = value; }
}
public
GridViewToggleButton ToggleButton {
get
;
set
; }
private
Binding toggleButtonVisibility;
public
Binding ToggleButtonVisibility {
get
{
return
toggleButtonVisibility; }
set
{ toggleButtonVisibility = value; }
}
public
CustomGridViewToggleRowDetailsColumn() {
// Set the EditTriggers property to None
this
.EditTriggers = GridViewEditTriggers.None;
}
public
override
bool
CanFilter() {
return
false
;
}
public
override
bool
CanGroup() {
return
false
;
}
public
override
bool
CanSort() {
return
false
;
}
public
override
FrameworkElement CreateCellElement( GridViewCell cell,
object
dataItem ) {
Cell = cell;
ToggleButton =
new
GridViewToggleButton {
Margin =
new
System.Windows.Thickness( 3 )
};
ToggleButton.Click +=
new
RoutedEventHandler( ToggleButton_Click );
if
(
this
.DataMemberBinding !=
null
) {
ToggleButton.SetBinding( GridViewToggleButton.IsCheckedProperty,
this
.DataMemberBinding );
}
if
( ToggleButtonVisibility !=
null
) {
ToggleButton.SetBinding( GridViewToggleButton.VisibilityProperty, ToggleButtonVisibility );
}
GridViewRow row = cell.ParentRow
as
GridViewRow;
row.SetBinding( GridViewRow.DetailsVisibilityProperty,
new
Binding(
"IsChecked"
) {
Source = ToggleButton,
Converter =
new
BooleanToVisibilityConverter(),
Mode = BindingMode.TwoWay
} );
return
ToggleButton;
}
void
ToggleButton_Click(
object
sender, RoutedEventArgs e ) {
RoutedEventArgs newEventArgs =
new
ToggleRowDetailsColumnRoutedEventArgs( ClickEvent, Cell );
RaiseEvent( newEventArgs );
}
}
public
class
ToggleRowDetailsColumnRoutedEventArgs : RoutedEventArgs {
public
GridViewCell Cell {
get
;
set
; }
public
GridViewRow Row {
get
{
return
Cell.ParentRow
as
GridViewRow; }
}
public
ToggleRowDetailsColumnRoutedEventArgs( RoutedEvent routedEvent, GridViewCell cell )
:
base
( routedEvent ) {
Cell = cell;
}
}
public
delegate
void
ToggleRowDetailsColumnRoutedEventHandler(
object
sender, ToggleRowDetailsColumnRoutedEventArgs e );
}
Tony