WPF Slider控件(NullReferenceException)

时间:2011-09-30 13:31:12

标签: c# wpf

我正在尝试在TextBlock中显示滑块控件的值。但是,当我尝试加载对话框时,我不断收到NullRerferenceException。

public partial class GeneralSettingsDialog : Window
{

    public GeneralSettingsDialog()
    {  
        InitializeComponent();
    }

    private void DistSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        DistTextBlock.Text = DistSlider.Value.ToString();
    }
}

XAML:

        <TabItem Header="Miscellaneous" Name="tabItem1" Background="#FFF0F0F0">
            <Grid Height="230" Background="#FFF0F0F0">
                <TextBlock Height="23" HorizontalAlignment="Left" Margin="13,13,0,0" Name="textBlock1" Text="Spacing" VerticalAlignment="Top" />
                <Slider Height="23" HorizontalAlignment="Left" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Margin="13,35,0,0" Name="DistSlider" VerticalAlignment="Top" Width="100" Interval="1" Maximum="50" Minimum="1" ValueChanged="DistSlider_ValueChanged" />
                <TextBlock Height="23" HorizontalAlignment="Left" Margin="111,35,0,0" Name="DistTextBlock" Text="TextBlock" VerticalAlignment="Top" />

            </Grid>
        </TabItem>

2 个答案:

答案 0 :(得分:4)

不完全确定为什么你的方式不起作用,我想当第一个值更改事件被抛出时控件没有完全初始化。但你可以直接在xaml中这样做而不需要任何代码:

TextBlock中的

直接绑定到滑块的当前值并删除值更改的事件处理程序:

 Text="{Binding ElementName=DistSlider, Path=Value}"

PS:

当您在InitializeComponent()之后附加到代码隐藏中滑块的值更改事件时,您的方法也应该正常工作:

public MainWindow()
{
  InitializeComponent();
  DistSlider.ValueChanged +=new RoutedPropertyChangedEventHandler<double>(DistSlider_ValueChanged);
}

private void DistSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    DistTextBlock.Text = DistSlider.Value.ToString();
}

答案 1 :(得分:3)

在您的XAML中,您在 DistSlider 之后定义了TextBlock DistTextBlock 。第一次加载XAML时,它将触发ValueChanged处理程序,而 DistTextBlock 将为null。您可以通过以下几种方式防范这种情况:

// 1. Naive, but least changes to your code
if (DistTextBlock != null)
{
    DistTextBlock.Text = DistSlider.Value.ToString();
}

@SvenG's excellent suggestion,它将逻辑移动到XAML(不需要ValueChanged处理程序):

<TextBlock Text="{Binding Value, ElementName=DistSlider}" ... />

最后,您可以使用ViewModel(或任何data context supporting INotifyPropertyChanged)来处理值的传入和传出。

使用绑定的重要部分是它允许您在XAML中放置任何string formatting right alongside its usage(例如,如果此滑块用于货币金额):

<TextBlock Text="{Binding Value, ElementName=DistSlider, StringFormat={}{0:C}}"

使用绑定的最后一个好处是.Net Framework 4.5, which allows you to specify a time delay prior to the binding updating its source。如果在昂贵的操作中使用绑定,这将允许您的GUI看起来更具反应性。

<Slider Value="{Binding DollarAmount, Delay=50}" ... />
<TextBlock Text="{Binding DollarAmount, StringFormat={}{0:C}}" ... />