2011-09-30 12 views
2

スライダコントロールの値をTextBlockに表示しようとしています。しかし、私はダイアログをロードしようとするとNullRerferenceExceptionを取得し続けます。WPFスライダコントロール(NullReferenceException)

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> 
+1

オブジェクトDistSlider.Valueがnullかどうかをデバッグして確認してください。 –

+0

メッセージボックスに値が表示されるので、問題はテキストブロックにあるようです。 – kr13

+0

XAMLを表示してください。クリスタルボールはありません。 :) –

答えて

4

正確にわかりません。スライダーの現在の値に直接結合し、値変更イベントハンドラ削除のTextBlockに

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

がPS:

しかし、あなたが背後にある任意のコードなしで、XAMLで直接そのように行うことができますあなたのアプローチはまた、正常に動作する必要の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(); 
} 
+0

これは本当にうまくいっています!ありがとう – kr13

3

をごXAMLであなたTextBlockDistTextBlockが定義されています。DistSliderの後にが定義されています。 XAMLが初めてロードされると、ValueChangedハンドラが起動し、DistTextBlockがnullになります。あなたは、いくつかの方法でこれを防御することができます

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

最後に、あなたがViewModelを使用することができます。

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

XAML(ValueChangedハンドラは必要ありません)にロジックを移動@SvenG's excellent suggestionがあり、 (または任意の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}}" ... /> 
+1

説明をありがとう!本当に役に立ちました。 – kr13

+0

親切な言葉をありがとう。 Delay Bindingプロパティは本当に役に立ちます。間違いなく4.5で試してみましょう。言及してくれてありがとう! – SvenG

+0

@SvenG:あなたは歓迎です、私は彼があなたのものを選ぶことを願っていました。イベントハンドラでダウン!今後の予定は、[.Net Framework 4.5 WPF changelog](http://msdn.microsoft.com/en-us/library/bb613588%28v=vs.110%29.aspx)を読むことをお勧めします。 – user7116

関連する問題