我有一个UserControl嵌入了一个ComboBox和一些与验证相关的东西。
在我尝试更新ItemsSource之前,它一直有效(当我更改第一个ComboBox“ ChoixResidence”时会发生这种情况):我收到“ System.NullReferenceException:'对象引用未设置为对象的实例。'“
[EDIT]请注意,它与常规ComboBox而不是ValComboBox一起使用。
Exception when updating ItemsSource screen capture
我尝试将ItemsSource设置为null,但没有成功。
UserControl: XAML:
<UserControl
x:Class="GestionGarages.Controls.ValComboBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:GestionGarages.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<StackPanel>
<TextBlock Margin="0,0,0,5" Text="{x:Bind Title, Mode=OneWay}"/>
<ComboBox x:Name="List"
Width="{x:Bind Width, Mode=OneWay}"
DisplayMemberPath="{x:Bind MemberPath, Mode=OneWay}"
SelectedValuePath="{x:Bind ValuePath, Mode=OneWay}"
SelectedValue="{x:Bind SelectedValue, Mode=TwoWay}">
</ComboBox>
<TextBlock
x:Name="DisplayErrorMessage"
Text="{x:Bind ErrorMessage, Mode=OneWay}"
FontSize="10"
Foreground="Red"
Height="14"/>
</StackPanel>
</Grid>
</UserControl>
后面的代码:
using System;
using System.Collections;
using System.ComponentModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
namespace GestionGarages.Controls
{
public sealed partial class ValComboBox : UserControl
{
public ValComboBox()
{
this.InitializeComponent();
Loaded += ValComboBox_Loaded;
}
private void ValComboBox_Loaded(object sender, RoutedEventArgs e)
{
Binding selectedIdemBinding = new Binding
{
Source = this,
Mode = BindingMode.TwoWay,
ElementName = "SelectedItem"
};
List.SetBinding(ComboBox.SelectedItemProperty, selectedIdemBinding);
}
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set {
SetValue(ItemsSourceProperty, value);
List.ItemsSource = value;
}
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(ValComboBox), new PropertyMetadata(null));
public object SelectedItem
{
get { return (object)GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); List.SelectedItem = SelectedItem; }
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(ValComboBox), new PropertyMetadata(null));
public string ValuePath
{
get { return (string)GetValue(ValuePathProperty); }
set { SetValue(ValuePathProperty, value); }
}
// Using a DependencyProperty as the backing store for ValuePath. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValuePathProperty =
DependencyProperty.Register("ValuePath", typeof(string), typeof(ValComboBox), new PropertyMetadata(""));
public string MemberPath
{
get { return (string)GetValue(MemberPathProperty); }
set { SetValue(MemberPathProperty, value); }
}
// Using a DependencyProperty as the backing store for MemberPath. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MemberPathProperty =
DependencyProperty.Register("MemberPath", typeof(string), typeof(ValComboBox), new PropertyMetadata(""));
public int SelectedValue
{
get { return (int)GetValue(SelectedValueProperty); }
set { SetValue(SelectedValueProperty, value); }
}
// Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedValueProperty =
DependencyProperty.Register("SelectedValue", typeof(int), typeof(ValComboBox), new PropertyMetadata(0));
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
// Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(ValComboBox), new PropertyMetadata(""));
public string ErrorMessage
{
get { return (string)GetValue(ErrorMessageProperty); }
set { SetValue(ErrorMessageProperty, value); }
}
// Using a DependencyProperty as the backing store for Field. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ErrorMessageProperty =
DependencyProperty.Register("ErrorMessage", typeof(string), typeof(ValTextBox), new PropertyMetadata(""));
public event SelectionChangedEventHandler SelectionChanged
{
add { List.SelectionChanged += value; }
remove { List.SelectionChanged -= value; }
}
public event PropertyChangedEventHandler PropertyChanged;
void SetValueDp(DependencyProperty property, object value,
[System.Runtime.CompilerServices.CallerMemberName] String p = null)
{
SetValue(property, value);
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
}
此代码中使用了此UserControl:
XAML:
<ContentDialog
x:Class="GestionGarages.Controls.AddModifContrat"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:GestionGarages.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:models="using:GestionGarages.Core.Models"
mc:Ignorable="d"
d:DesignHeight="1000"
d:DesignWidth="800"
Height="Auto"
Width="Auto"
Title="Ajout / Modification Contrat"
PrimaryButtonText="OK"
SecondaryButtonText="Annuler"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick"
Background="{ThemeResource ContentDialogBackgroundThemeBrush}"
Foreground="{ThemeResource ContentDialogContentForegroundBrush}"
Margin="{ThemeResource ContentDialogBorderWidth}">
<Grid x:Name="AddModifContratGrid">
<StackPanel Orientation="Vertical">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<local:ValComboBox
Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
x:Name="ChoixResidence"
Title="Résidence"
Width="400"
MemberPath="Nom"
ValuePath="ResidenceId"
SelectionChanged="ChoixResidence_SelectionChanged"
ErrorMessage=""/>
<local:ValComboBox
Grid.Row="1" Grid.Column="0"
x:Name="ChoixGarage"
Title="Garage"
Width="200"
MemberPath="Numero"
ValuePath="GarageId"
SelectionChanged="ChoixGarage_SelectionChanged"
ErrorMessage=""/>
</Grid>
</StackPanel>
</Grid>
</ContentDialog>
(部分)后面的代码:
private void ChoixResidence_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Residence residence = residences.Where(g => g.ResidenceId == (int)ChoixResidence.SelectedValue).FirstOrDefault();
garages = residence.Garages.ToList();
ChoixGarage.ItemsSource = garages;
ChoixGarage.SelectedItem = garages.FirstOrDefault();
}
private void ChoixGarage_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
garage = garages.Where(g => g.GarageId == (int)ChoixGarage.SelectedValue).FirstOrDefault();
}