输入值时出现NullReferenceException

时间:2012-10-11 18:05:29

标签: c# wpf textbox nullreferenceexception

这是我的整个代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void sldChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        double red, green, blue;
        red = sldRed.Value;
        green = sldGreen.Value;
        blue = sldBlue.Value;
        changeColors(red, green, blue);
    }

    private void inputChanged(object sender, TextChangedEventArgs e)
    {
        double red, green, blue;
        red = Convert.ToDouble(txtRed.Text);
        green = Convert.ToDouble(txtGreen.Text);
        blue = Convert.ToDouble(txtBlue.Text);
        sldRed.Value = red;
        sldGreen.Value = green;
        sldBlue.Value = blue;
        changeColors(red, green, blue);
    }

    void changeColors(double red, double green, double blue)
    {

    }

    private void Window_Loaded_1(object sender, RoutedEventArgs e)
    {
        txtRed.Text = Convert.ToString(sldRed.Value);
        txtGreen.Text = Convert.ToString(sldGreen.Value);
        txtBlue.Text = Convert.ToString(sldBlue.Value);
    }
}

这是我的整个.xaml代码。

<Grid x:Name="frmGrid" Margin="0,0,2,0">
    <Slider x:Name="sldRed" HorizontalAlignment="Left" Margin="57,10,0,0" VerticalAlignment="Top" Width="757" ValueChanged="sldChanged" ClipToBounds="True" Maximum="255" TickPlacement="BottomRight" IsSnapToTickEnabled="True" SmallChange="1" Value="1"/>
    <Slider x:Name="sldBlue" HorizontalAlignment="Left" Margin="57,76,0,0" VerticalAlignment="Top" Width="757" ValueChanged="sldChanged" ClipToBounds="True" Maximum="255" TickPlacement="BottomRight" IsSnapToTickEnabled="True" SmallChange="1" Value="1"/>
    <Slider x:Name="sldGreen" HorizontalAlignment="Left" Margin="57,45,0,0" VerticalAlignment="Top" Width="757" ValueChanged="sldChanged" ClipToBounds="True" Maximum="255" TickPlacement="BottomRight" IsSnapToTickEnabled="True" SmallChange="1" Value="1"/>
    <Label Content="Red" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
    <Label Content="Blue" HorizontalAlignment="Left" Margin="10,72,0,0" VerticalAlignment="Top"/>
    <Label Content="Green" HorizontalAlignment="Left" Margin="10,41,0,0" VerticalAlignment="Top"/>
    <TextBox x:Name="txtRed" HorizontalAlignment="Left" Height="23" Margin="819,9,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="41" TextChanged="inputChanged"/>
    <TextBox x:Name="txtBlue" HorizontalAlignment="Left" Height="23" Margin="819,74,0,0" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="41" TextChanged="inputChanged"/>
    <TextBox x:Name="txtGreen" HorizontalAlignment="Left" Height="23" Margin="819,41,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="41" TextChanged="inputChanged" Text="1"/>

</Grid>

您可以看到我为这些文本框分配了一个值以供测试。

出于某种原因,我不断收到此错误 enter image description here

这是指这两行。

green = Convert.ToDouble(txtGreen.Text);
blue = Convert.ToDouble(txtBlue.Text);

注意它上面的类似线如何完美地运作

red = Convert.ToDouble(txtRed.Text);

我在C#方面不是那么有经验,我在阅读那些错误方面也没有经验。 如果你知道我为什么会收到这个错误并且可能为我提供一个可能的解决方案,那将非常感激。

PS:我认为可能对您有用的东西,我在程序启动之前就会收到此错误。

这里有2张截图,其中1根本没有加载,而第2张完全加载&amp;作品。 enter image description here enter image description here

4 个答案:

答案 0 :(得分:2)

txtRed and txtBlue不包含值。但是txtRed包含值

您可以添加验证脚本,以确保您的控件不为空

答案 1 :(得分:0)

当输入更改时,事件处理程序将触发。如果你在任何一个方框中点击退格键,你的Text现在是一个空字符串或null。你不能把它们变成双打。尝试使用Double.TryParse()而不是Convert.ToDouble()来确定它是否实际上是一个可解析的输入,如下所示:

private void inputChanged(object sender, TextChangedEventArgs e)
{
    double red, green, blue;

    if(Double.TryParse(txtRed.Text, out red) &&
        Double.TryParse(txtGreen.Text, out green) &&
        Double.TryParse(txtBlue.Text, out blue)) 
    {
        sldRed.Value = red;
        sldGreen.Value = green;
        sldBlue.Value = blue;
        changeColors(red, green, blue);
    }
}

如果RGB TextBox中的所有值都有效,则if语句为true,红色,绿色和蓝色将正确设置。

这当然是假设sldGreen和sldBlue不为空。

答案 2 :(得分:0)

我认为问题出在您的Window_Loaded_1上,它会更改文本框的文本值,从而导致调用inputChanged方法。尝试评论Window_Loaded_1中的代码并查看异常是否仍然发生。

解决此问题的一种方法是使用绑定将滑块和文本框的值连接在一起。 你的xaml应该是这样的:

<Grid x:Name="frmGrid" Margin="0,0,2,0">
    <Slider x:Name="sldRed" HorizontalAlignment="Left" Margin="57,10,0,0" VerticalAlignment="Top" Width="757" ValueChanged="sldChanged" ClipToBounds="True" Maximum="255" TickPlacement="BottomRight" IsSnapToTickEnabled="True" SmallChange="1" Value="1"/>
    <Slider x:Name="sldBlue" HorizontalAlignment="Left" Margin="57,76,0,0" VerticalAlignment="Top" Width="757" ValueChanged="sldChanged" ClipToBounds="True" Maximum="255" TickPlacement="BottomRight" IsSnapToTickEnabled="True" SmallChange="1" Value="1"/>
    <Slider x:Name="sldGreen" HorizontalAlignment="Left" Margin="57,45,0,0" VerticalAlignment="Top" Width="757" ValueChanged="sldChanged" ClipToBounds="True" Maximum="255" TickPlacement="BottomRight" IsSnapToTickEnabled="True" SmallChange="1" Value="1"/>
    <Label Content="Red" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
    <Label Content="Blue" HorizontalAlignment="Left" Margin="10,72,0,0" VerticalAlignment="Top"/>
    <Label Content="Green" HorizontalAlignment="Left" Margin="10,41,0,0" VerticalAlignment="Top"/>

    <TextBox x:Name="txtRed" HorizontalAlignment="Left" Height="23" Margin="819,9,0,0" TextWrapping="Wrap" Text="{Binding ElementName=sldRed, Path=Value, Mode=TwoWay}" VerticalAlignment="Top" Width="41"/>

    <TextBox x:Name="txtBlue" HorizontalAlignment="Left" Height="23" Margin="819,74,0,0" TextWrapping="Wrap" Text="{Binding ElementName=sldBlue, Path=Value, Mode=TwoWay}" VerticalAlignment="Top" Width="41"/>

    <TextBox x:Name="txtGreen" HorizontalAlignment="Left" Height="23" Margin="819,41,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="41" Text="{Binding ElementName=sldGreen, Path=Value, Mode=TwoWay}"/>


</Grid>

您的代码应如下所示:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void sldChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        red = sldRed.Value;
        green = sldGreen.Value;
        blue = sldBlue.Value;
        changeColors(red, green, blue);
    }

    void changeColors(double red, double green, double blue)
    {

    }
}

您可以摆脱inputChanged并仅响应滑块更改

答案 3 :(得分:0)

失败的原因是因为在最初在xaml中创建滑块时会调用valuechanged事件并包含:Value =“1”。在创建其他控件之前会引发事件,从而引发null异常。

WPF很大程度上建立在绑定的概念之上,你应该尽可能地利用它,因为它会让你的生活更轻松。我修改了你的代码,向你展示如何使用绑定。

XAML

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        x:Name="TheMainWindow">
    <Grid x:Name="frmGrid" Margin="0,0,2,0">
        <Slider x:Name="sldRed" HorizontalAlignment="Left" Margin="57,10,0,0" VerticalAlignment="Top" Width="757" ClipToBounds="True" Maximum="255" TickPlacement="BottomRight" IsSnapToTickEnabled="True" 
                SmallChange="1" Value="{Binding Path=Red, ElementName=TheMainWindow, Mode=TwoWay}"/>
        <Slider x:Name="sldBlue" HorizontalAlignment="Left" Margin="57,76,0,0" VerticalAlignment="Top" Width="757" ClipToBounds="True" Maximum="255" TickPlacement="BottomRight" IsSnapToTickEnabled="True" 
                SmallChange="1" Value="{Binding Path=Blue, ElementName=TheMainWindow, Mode=TwoWay}"/>
        <Slider x:Name="sldGreen" HorizontalAlignment="Left" Margin="57,45,0,0" VerticalAlignment="Top" Width="757" ClipToBounds="True" Maximum="255" TickPlacement="BottomRight" IsSnapToTickEnabled="True"
                SmallChange="1" Value="{Binding Path=Green, ElementName=TheMainWindow, Mode=TwoWay}"/>
        <Label Content="Red" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
        <Label Content="Blue" HorizontalAlignment="Left" Margin="10,72,0,0" VerticalAlignment="Top"/>
        <Label Content="Green" HorizontalAlignment="Left" Margin="10,41,0,0" VerticalAlignment="Top"/>
        <TextBox x:Name="txtRed" HorizontalAlignment="Left" Height="23" Margin="819,9,0,0" TextWrapping="Wrap" Text="{Binding Path=Red, ElementName=TheMainWindow}" VerticalAlignment="Top" Width="41"/>
        <TextBox x:Name="txtBlue" HorizontalAlignment="Left" Height="23" Margin="819,74,0,0" TextWrapping="Wrap" Text="{Binding Path=Blue, ElementName=TheMainWindow}" VerticalAlignment="Top" Width="41" />
        <TextBox x:Name="txtGreen" HorizontalAlignment="Left" Height="23" Margin="819,41,0,0" TextWrapping="Wrap" VerticalAlignment="Top"  Text="{Binding Path=Green, ElementName=TheMainWindow}" Width="41" />
    </Grid>
</Window>

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private double _red = 1;
    public double Red
    {
        get { return _red; }
        set
        {
            _red = value;
            OnPropertyChanged("Red");
        }
    }

    private double _green = 1;
    public double Green
    {
        get { return _green; }
        set
        {
            _green = value;
            OnPropertyChanged("Green");
        }
    }

    private double _blue = 1;
    public double Blue
    {
        get { return _blue; }
        set
        {
            _blue = value;
            OnPropertyChanged("Blue");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}