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