2011-09-30 2 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의 바인딩에

하고 값 변경 이벤트 핸들러 제거 :하지만 당신은 뒤에 코드없이 XAML에서 직접 그런 식으로 할 수

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(); 
} 
+0

이것은 정말 잘 돌아갔습니다! 감사합니다 – kr13

3

당신의 XAML에서는 TextBlockDistTextBlockDistSlider 다음에 으로 정의됩니다. 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에 대한 논리 (A 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

관련 문제