【问题标题】:WPF MVVM User Control binding issuesWPF MVVM 用户控件绑定问题
【发布时间】:2010-12-15 14:15:31
【问题描述】:

我有一个使用 MVVM 的应用程序。我在主窗口上有几个项目绑定到该窗口的 ViewModel。当我运行它时,一切正常。但是,当我将用户控件添加到主窗口并尝试绑定到其依赖对象之一时,它会引发异常(“对象引用未设置为对象的实例”)。异常窗口只是在屏幕上弹出,并没有链接到代码中的任何特定位置。异常中的任何其他信息都没有帮助。

我已尽力追查此事,但我没有任何运气。在 window 的构造函数中,我检查并验证了它尝试绑定的项目是否存在并且是一个对象 (int[])。我还在构造函数中手动设置了有问题的属性。 如果有人能注意到什么,这里有一些代码 sn-ps。

这里是我使用用户控件并尝试绑定到“视图”属性的地方

<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" />

这是我尝试绑定到的视图模型中的字段:

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

并在视图模型的构造函数中实例化对象

histogramData = new int[256];

最后是用户控件中的视图属性

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); }
    }

我不知道这是否足以解决任何问题,所以如果需要更多代码,请告诉我。如果有人愿意看这个,我也可以压缩这个项目。提前致谢。

【问题讨论】:

    标签: wpf user-controls mvvm binding


    【解决方案1】:

    您可以在依赖属性上初始化 FrameworkPropertyMetaData 时尝试初始化数组。

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

    我认为程序在设法将依赖属性绑定到 viewmodel 属性之前可能会遇到空引用异常。


    好的,我已经查看了您的示例项目,并认为我有一个解决方案。

    将视图模型中的int[] 更改为List&lt;int&gt;。 我不确定为什么会这样。我希望list&lt;int&gt; 不适合你没有技术原因。

    这是我在解决方案中所做的更改

    在视图模型中

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

    在arraycontrol代码隐藏中

    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); }
            }
    

    在arraycontrol.xaml 中。刚刚添加了列表框以显示数据绑定工作

    <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>
    

    【讨论】:

    • 我试过了(请参阅我上面的最后一条评论)但它没有用:(
    • 抱歉,我不确定您指的是哪条评论。您是否尝试过用 new int[256] 替换上一个代码 sn-p 中的 null?
    • 如果你想发送整个项目,我会看看。虽然我对 wpf 还很陌生,所以我可能也无法正常工作。
    • 我在一个很小的项目中重新创建了这个问题,可以在这里获得:mediafire.com/?tjntymmi5dz。它是 rar 格式的,如果这会是一个问题,请告诉我,我可以压缩它。谢谢
    • 我知道使用列表有效(如字符串),但我真的想使用一个数组,以便我可以按索引插入值。我猜字符串和列表可以工作,因为它们可以为空?感谢您花时间看它!
    【解决方案2】:

    使用调试器获取异常堆栈跟踪。这应该可以帮助您缩小问题范围。

    有几种方法可以做到这一点。例如,您应该能够只查看异常的详细信息。或者您可以打开一个监视窗口并输入表达式$exception,然后点击评估。

    【讨论】:

    • 当我查看详细信息(我以前做过)时,堆栈跟踪在“InitializeComponent();”处停止在主窗口代码后面。如果我进入 InitializeComponent 异常窗口在不同的地方弹出,细节和以前一样。
    • 通常如果调试器在 InitializeComponent 中死机是一些无效的 xaml
    • 是的,它必须在您的 xaml 中。 InitializeComponent 尝试实例化在 xaml 中指定的所有控件。这可能是中世纪的,但请尝试删除 .xaml 中的控件,直到不弹出异常为止。
    • 我创建了一个新的用户控件,它只有一个依赖对象,它是一个字符串,它可以工作。然后我将依赖对象类型更改为 int[] 并且它以与以前相同的方式失败。我在 frameworkpropertymetadata 中指定默认值为 null,我认为这就是让我搞砸的原因。我试过'new int [256]',但也失败了。关于默认值的任何建议,或者您认为我在找错树。
    猜你喜欢
    • 2011-04-07
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多