locked
System.AccessViolationException when using indexed properties RRS feed

  • General discussion

  • This is not a question, but stating a fact. Here's a simple test program. DataItem has an indexed property. MainPage uses an instance of this class as a data context. When I click the button, DataContext is set to null. When I bind to textboxes via indexed property, programme crashes with AccessViolationException after clicking the button. When I bind via wrapped properties Prop1 and Prop2, values disappear from controls and there is no crash, as expected. Is this an error or by definition? I am really glad I was able to isolate this problem, these crashes were driving me mad and I could not find out why. I wanted to save myself a bit of coding with indexed properties, but it looks like I have to rewrap them with normal properties and save myself a headache :)

    Ivan

        public class DataItem : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

            protected void RaisePropertyChanged(string property)
            {
                if(PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(property));
            }

            Dictionary<int, int> _Values;

            public int Prop1
            {
                get { return this[1]; }
                set { this[1] = value; RaisePropertyChanged("Prop1"); }
            }

            public int Prop2
            {
                get { return this[2]; }
                set { this[2] = value; RaisePropertyChanged("Prop2"); }
            }

            public int this[int index]
            {
                get
                {
                    int value;
                    if (_Values == null)
                        _Values = new Dictionary<int, int>();
                    if (!_Values.TryGetValue(index, out value))
                        _Values[index] = value = 0;
                    return value;
                }
                set
                {
                    if (this[index] != value)
                    {
                        _Values[index] = value;
                        RaisePropertyChanged("item[]");
                    }
                }
            }
        }

    MainPage.xaml.cs:

        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
                DataContext = new DataItem();
            }

            /// <summary>
            /// Invoked when this page is about to be displayed in a Frame.
            /// </summary>
            /// <param name="e">Event data that describes how this page was reached.  The Parameter
            /// property is typically used to configure the page.</param>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                DataContext = null;
            }
        }

    and XAML:

    <Page
        x:Class="Indexed.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Indexed"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">

        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <StackPanel Orientation="Vertical" >
                <TextBox Text="{Binding [1], Mode=TwoWay}"/>
                <TextBox Text="{Binding [2], Mode=TwoWay}"/>
                <!--<TextBox Text="{Binding Prop1, Mode=TwoWay}"/>
                <TextBox Text="{Binding Prop2, Mode=TwoWay}"/>-->
                <Button Content="Crash!" Click="Button_Click"/>
            </StackPanel>
        </Grid>
    </Page>

    Thursday, September 26, 2013 9:09 PM