English 中文(简体)
WPF MVVM User Control binding issues
原标题:

I have an application that uses MVVM. I have several items on the main window that bind to the ViewModel for that window. When I run it everything works. However, when I add a user control to the main window and try to bind to one of its dependency objects it throws an exception (“Object reference not set to an instance of an object”). The exception window just pops up on the screen and does not link to any particular place in code. And any other information in the exception is not helpful.

I’ve tried my best to trace this down but I’m not having any luck. In the constructor of window I’ve checked and verified that the item that it’s attempting to bind to exists and is an object (int[]). I’ve also manually set the property in the constructor with problems. Here are some code snippets if anyone can notice anything.

Here is where I use the user control and attempt to bind to the view property

<local:Histogram Grid.Row="2" Grid.ColumnSpan="2"
                                        View="{Binding Path=HistogramData}"             
                                        Foreground="{DynamicResource FontColor}"
                                        BucketStroke="{DynamicResource BucketStrokeBrush}"
                                        BucketFill="{DynamicResource BucketFillBrush}"
                                        SelectedBrush="{DynamicResource FamilyEditListViewSelectedBrush}"
                                        DisabledForegroundBrush="{DynamicResource DisabledForegroundBrush}"
                                        AxisBrush="{DynamicResource AxisBrush}" 
                                        MaxHeight="130" />

Here is the field in the view model that I am attempting to bind to:

public int[] HistogramData
    {
        get
        {
            return histogramData;
        }
        set
        {
            if (value != histogramData)
            {
                histogramData = value;
                RaisePropertyChanged("HistogramData");
            }
        }
    }

And in the constructor of the view model I instantiate the object

histogramData = new int[256];

And finally here is the view property in the user control

public static readonly DependencyProperty ViewProperty =
        DependencyProperty.Register("View", 
                                    typeof(int[]), 
                                    typeof(Histogram),
                                    new FrameworkPropertyMetadata(null,
                                                                  FrameworkPropertyMetadataOptions.AffectsRender,
                                                                  new PropertyChangedCallback(ViewProperty_Changed)));

    public int[] View
    {
        get { return (int[])GetValue(ViewProperty); }
        set { SetValue(ViewProperty, value); }
    }

I don t know if this is enough information to solve anything so if more code is req please let me know. I could also zip up the project if someone is so inclined to look at that. Thanks in advance.

最佳回答

You could try initialising the array when you initialise FrameworkPropertyMetaData on the dependency property.

 new FrameworkPropertyMetadata(new int [256],
                              FrameworkPropertyMetadataOptions.AffectsRender,  
                              new PropertyChangedCallback(ViewProperty_Changed))

I think that the program might be hitting a null reference exception before it manages to bind the dependency property to the viewmodel property.


Ok I ve had a look at your example project and think i have a solution.

change the int[] in the viewmodel to a List<int>. I m not sure why this works. I hope there is no technical reason that list<int> is not suitable for you.

Here is what I have changed in the solution

in the viewmodel

public List<int> CustomData
        {
            get
            {
                return new List<int>(){0,1,2,3};
            }
            set
            {
            }
        }

In the arraycontrol codebehind

public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data",
                                        typeof(List<int>),
                                        typeof(ArrayControl),
                                        new FrameworkPropertyMetadata(new List<int>()));

        public List<int> Data
        {
            get { return (List<int>)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }

In arraycontrol.xaml. Just added listbox to show data binding working

<UserControl x:Class="UserControlWithArray.Controls.ArrayControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <Grid>
             <TextBlock x:Name="MessageTextBlock" Text="ArrayControl"/> 
        <ListBox ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=Data}"/>
    </Grid>
</UserControl>
问题回答

Use the debugger to get an exception stack trace. That should help you narrow the problem down.

There are several ways to do this. For example, you should be able to just view the details of the exception. Or you could open a watch window and enter the expression $exception and then hit evaluate.





相关问题
WPF convert 2d mouse click into 3d space

I have several geometry meshes in my Viewport3D, these have bounds of (w:1800, h:500, d:25). When a user clicks in the middle of the mesh, I want the Point3D of (900, 500, 25)... How can I achieve ...

Editing a xaml icons or images

Is it possible to edit a xaml icons or images in the expression design or using other tools? Is it possible to import a xaml images (that e.g you have exported) in the expression designer for editing?...

WPF: writing smoke tests using ViewModels

I am considering to write smoke tests for our WPF application. The question that I am faced is: should we use UI automation( or some other technology that creates a UI script), or is it good enough to ...

WPF - MVVM - NHibernate Validation

Im facing a bit of an issue when trying to validate a decimal property on domain object which is bound to a textbox on the view through the viewmodel. I am using NHibernate to decorate my property on ...

How do WPF Markup Extensions raise compile errors?

Certain markup extensions raise compile errors. For example StaticExtension (x:Static) raises a compile error if the referenced class cannot be found. Anyone know the mechanism for this? Is it baked ...

WPF design-time context menu

I am trying to create a custom wpf control, I m wondering how I can add some design-time features. I ve googled and can t seem to get to my goal. So here s my simple question, how can I add an entry ...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签