TLDR: 別の無関係な要素にデータ バインディングと値コンバーターがある場合、XAML がボタン要素を解析すると、Nullreference 例外がスローされます。ボタンがコメントアウトされるか、データバインディングが削除されると、フォームが機能します。
複数のコントロールを持つ DataTemplate を持つリスト ボックスを持つ WPF UserControl があります。また、コントロール内のさまざまな場所で使用する bool から可視性値へのコンバーターもあります。コンバーターの新しい静的参照をコントロールに追加し (ブール値と可視性の値が異なります)、それをラベルにバインドすると、コントロールの読み込み時に突然アプリがクラッシュします。
バインディングを外すと、すべてが正常に戻ります。ただし、コンバーターに問題はありません。コンストラクターと convert メソッドにブレークポイントを配置しましたが、決して到達しません。例外は、XAML の解析であり、ラベルではなく、宣言された最初のボタンであり、ラベルとは 100% 無関係です。ラベルから値コンバーターのバインディングを削除すると、XAML は正しく解析され、ボタンに問題はありません。
ただし、複雑なことに、XAML でそのボタンと他のすべてのボタンをコメントアウトすると、正しく解析され、値コンバーターは問題なく動作します。
私は何が欠けていますか?
XAML:
<UserControl x:Class="Customer_Management.OpportunityControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:l="clr-namespace:Customer_Management"
d:DesignHeight="300" d:DesignWidth="300" MaxHeight="200" BorderBrush="DarkGray" BorderThickness="1" x:Name="ucOpp">
<UserControl.Resources>
<l:NullToVisibilityConverter NullValue="Hidden" NonNullValue="Visible" x:Key="NullToHidden"></l:NullToVisibilityConverter>
<l:BoolToVisibilityConverter TrueValue="Visible" FalseValue="Hidden" x:Key="TrueToVisible"></l:BoolToVisibilityConverter>
<l:BoolToVisibilityConverter TrueValue="Hidden" FalseValue="Visible" x:Key="FalseToVisible"></l:BoolToVisibilityConverter>
</UserControl.Resources>
<ScrollViewer>
<ListBox Name="lbxOpps" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="DarkGray" BorderThickness="1">
<Grid>
<StackPanel>
<TextBlock Text="{Binding Path=Opportunity.Name}" Margin="0,1,3,1"></TextBlock>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Opportunity.Amount, StringFormat=\{0:C\}}" Margin="0,1,3,1"></TextBlock>
<Button Name="btnFinishOrder" Click="btnFinishOrder_Click">Finish Order</Button>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0,1,3,1">Invoice #</TextBlock>
<TextBox Name="tbxInvoiceNumber" Text="{Binding Path=InvoiceNumber}"></TextBox>
</StackPanel>
<ListBox ItemsSource="{Binding Path=Batches}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label FontWeight="Bold" Visibility="{Binding Path=IsOcc, Converter={StaticResource TrueToVisible}}">OCC #:</Label>
<ComboBox Margin="0,0,0,0" Name="cboLicense" SelectedValue="{Binding Path=SLicense}" DisplayMemberPath="LicenseID"
SelectedValuePath="LicenseID" ItemsSource="{Binding ElementName=ucOpp, Path=Licenses}">
</ComboBox>
<!--<Button Margin="0,0,3,0" DataContext="{Binding ElementName=cboLicense}" Click="Button_ClearContorl">X</Button>-->
<Label Margin="0,0,3,0" >R #:</Label>
<!--<Button ToolTip="Click to change" Name="btnLicFile" Click="Button_Click" >LIC File</Button>-->
<!--<Button Margin="0,0,3,0" DataContext="{Binding ElementName=btnLicFile}" Click="Button_ClearContorl" ToolTip="Clear">X</Button>-->
<Label Margin="0,0,3,0" >P #:</Label>
<ComboBox Margin="0,0,0,0" Name="cbxPNum" SelectedValue="{Binding Path=PNum}" DisplayMemberPath="Name"
SelectedValuePath="Id" ItemsSource="{Binding ElementName=ucOpp, Path=Nums}">
</ComboBox>
<!--<Button Margin="0,0,3,0" DataContext="{Binding ElementName=cbxPNum}" Click="Button_ClearContorl" ToolTip="Clear">X</Button>-->
<Label Margin="0,0,3,0" >U #:</Label>
<ComboBox Margin="0,0,0,0" Name="cbxUNum" SelectedValue="{Binding Path=UNum}" DisplayMemberPath="Name"
SelectedValuePath="Id" ItemsSource="{Binding ElementName=ucOpp, Path=Nums}">
</ComboBox>
<!--<Button Margin="0,0,3,0" DataContext="{Binding ElementName=cbxUNum}" Click="Button_ClearContorl" ToolTip="Clear">X</Button>-->
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
<Label HorizontalAlignment="Stretch" Background="LawnGreen" FontSize="24" Opacity="0.8" VerticalAlignment="Stretch" Visibility="{Binding Path=IsProcessing, Converter={StaticResource TrueToVisible}}"></Label>
<Label HorizontalAlignment="Center" FontSize="24" VerticalAlignment="Center" Visibility="{Binding Path=IsProcessing, Converter={StaticResource TrueToVisible}}">Processing...</Label>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
バリューコンバーター:
public sealed class BoolToVisibilityConverter : IValueConverter
{
public Visibility TrueValue { get; set; }
public Visibility FalseValue { get; set; }
public BoolToVisibilityConverter()
{
// set defaults
TrueValue = Visibility.Visible;
FalseValue = Visibility.Collapsed;
}
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (!(value is bool))
return null;
return (bool)value ? TrueValue : FalseValue;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (Equals(value, TrueValue))
return true;
if (Equals(value, FalseValue))
return false;
return null;
}
}