2

TLDR: 当另一个不相关的元素具有数据绑定和值转换器时,XAML 解析任何按钮元素时会引发 Nullreference 异常。当按钮被注释掉或数据绑定被删除时,表单就可以工作了。

我有一个 WPF UserControl,其中有一个列表框,其中有一个 DataTemplate,其中有多个控件。我还有一个布尔到可见性值转换器,我在控件的不同位置使用它。我将转换器的新静态引用添加到控件(与可见性值不同的布尔值)并将其绑定到标签,突然应用程序在加载控件时崩溃。

我取下绑定,一切都好起来了。不过转换器没有问题。我在它的构造函数和转换方法中设置了断点,但它永远不会到达它。例外是在 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;
    }
}
4

0 回答 0