Элемент управления WPF Slider (NullReferenceException) - PullRequest
2 голосов
/ 30 сентября 2011

Я пытаюсь отобразить значение элемента управления ползунка в 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 ]

4 голосов
/ 30 сентября 2011

Не совсем уверен, почему ваш путь не работает, я думаю, что элементы управления не полностью инициализированы, когда генерируется событие первого изменения значения.Но вы можете сделать это напрямую в xaml без какого-либо кода:

в TextBlock, привязать непосредственно к текущему значению ползунка и удалить обработчик события измененного значения:

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

PS:

Когда вы присоединяете событие изменения значения ползунка в codebehind после 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();
}
3 голосов
/ 30 сентября 2011

В вашем XAML есть TextBlock DistTextBlock , определенный после DistSlider .Когда XAML загружается в первый раз, он запускает обработчик ValueChanged и DistTextBlock будет нулевым.Вы можете защититься от этого несколькими способами:

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

Существует превосходное предложение @ SvenG , которое перемещает логику в XAML (нет необходимости в обработчике ValueChanged):

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

Наконец, вы можете использовать ViewModel (или любой контекст данных, поддерживающий INotifyPropertyChanged) для обработки передачи значения и от него.

Важной частью использования привязки является то, что она позволяет поместить любое форматирование строки вместе с его использованием в XAML (скажем, если этот ползунок был для суммы в валюте):

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

Последний бонус от использования привязки выходит в .Net Framework 4.5, которая позволяет вам указать задержку перед обновлением привязки ее источника .Это позволит вашему графическому интерфейсу выглядеть более реактивным, если привязка используется в дорогостоящих операциях.

<Slider Value="{Binding DollarAmount, Delay=50}" ... />
<TextBlock Text="{Binding DollarAmount, StringFormat={}{0:C}}" ... />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...