Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi Prism/Compiler    [ Add a report in this area ]  
Report #:  92872   Status: Open
using notify in generics problem
Project:  Embarcadero Prism Build #:  4.0.27.843
Version:    1.1 Submitted By:   Hugo Logmans
Report Type:  Crash / Data loss / Total failure Date Reported:  4/5/2011 11:51:02 PM
Severity:    Serious / Highly visible problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   282578
Resolution: None (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 1
Description
When using a public property with the 'notify' keyword on a generic, AND a public property on a typed instance, the program will runtime crash on modifying the property in the class. See code below.

Added by Sysop
<<<<<<
This issue still exists in Delphi Prism XE Update1.
>>>>>>
Steps to Reproduce:
Example:

  ListThingy<T> = public class
  private
  public
    property Sum : Int64; notify;
  end;

  ListThingyInt64 = public class(ListThingy<Int64>)
  private
  public
    property Count : Int64; notify;

    method ChangeALot;
  end;

  Window1 = public partial class(System.Windows.Window)
  private
    method Button_Click(sender: System.Object; e: System.Windows.RoutedEventArgs);
  public
    constructor;
    property Things : ListThingyInt64 := new ListThingyInt64;
  end;
  
implementation

constructor Window1;
begin
  InitializeComponent();
end;
  
method Window1.Button_Click(sender: System.Object; e: System.Windows.RoutedEventArgs);
begin
  Things.ChangeALot;
end;

method ListThingyInt64.ChangeALot;
begin
  Sum := Sum + 2;
  Count := Count + 1;   /// It crashes on this line
end;



And the corresponding XAML file:

<?xml version='1.0' encoding='utf-8' ?>
<Window x:Class="WpfCheckGenericNotify.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
  <Grid>
        <StackPanel Orientation="Vertical" DataContext="{Binding Path=Things}">
            <Label Content="{Binding Path=Count}" />
            <Label Content="{Binding Path=Sum}" />
            <Button Content="Extra getal" Click="Button_Click" />
        </StackPanel>

    </Grid>
</Window>



1) Is this a bug?
2) What would be a good workaround until a fix is available

Crash:
System.TypeLoadException was unhandled
Message=Could not load type 'WpfCheckGenericNotify.ListThingy`1' from assembly 'WpfCheckGenericNotify, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null'.
Source=WpfCheckGenericNotify
TypeName=WpfCheckGenericNotify.ListThingy`1
StackTrace:
at WpfCheckGenericNotify.ListThingyInt64.set_Count(Int64 value)
at WpfCheckGenericNotify.ListThingyInt64.ChangeALot() in c:\test\wpf\WpfCheckGenericNotify\WpfCheckGenericNotify\WpfCheckGenericNotify\Window1.xaml.pas:line 56
at WpfCheckGenericNotify.Window1.Button_Click(Object sender, RoutedEventArgs e) in c:\test\wpf\WpfCheckGenericNotify\WpfCheckGenericNotify\WpfCheckGenericNotify\Window1.xaml.pas:line 50
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(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)
at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run()
at WpfCheckGenericNotify.App.Main()
InnerException:
Workarounds
Carlo Kok suggested:
Implement the notify logic manually. implement INotifyPropertyChanged,
add the event required by that interface and call it from the setter of
Count (if value <> fCount)


ListThingyInt64 = public class(ListThingy<Int64>)
private
fCount: Integer;
method SetCount(aCount: Integer);
public
property Count : Int64 read fCount write set_Count;

method ChangeALot;
end;

method ListThingyInt64.SetCount(aCount: Integer);
begin
if fCount <> aCount then begin
PropertyChanging(new PropertyChangoingEventArgs('Count'));
fCpount := aCount;
PropertyChanged(new PropertyChangedEventArgs('Count'));
end;
end;
Attachment
None
Comments

Hugo Logmans at 4/6/2011 2:21:05 AM -
The workaround involves a lot of code (setters for each property) and a risk of typos when calling the PropertyChanged...

Tomohiro Takahashi at 4/9/2011 6:37:08 PM -
Hugo-san
Indeed, 'Delphi Prism XE Update1' still have your issue.

Server Response from: ETNACODE01