У меня есть UserControl, встраивающий ComboBox и некоторые вещи, связанные с проверкой.
Это работает, пока я не пытаюсь обновить ItemsSource (это происходит, когда я изменяю первый ComboBox "ChoixResidence"): я получаю "System. NullReferenceException: 'Ссылка на объект не установлена для экземпляра объекта.' '
[EDIT] Следует отметить, что он работает с обычным ComboBox вместо ValComboBox.
Исключение при обновлении Снимок экрана ItemsSource
Я пытался установить для 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));
}
}
}
Этот пользовательский элемент управления используется в этом коде:
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();
}