duney
duney

Reputation: 157

How can I have a Label change dynamically based on a Slider Value?

I'm writing a grade calculator and I currently have a slider with a textbox beside it which displays the current value of the slider:

    <Slider Name="gradeSlider"
            Grid.Row="3"
            Grid.Column="2"
            VerticalAlignment="Center"
            Minimum="40"
            Maximum="100"
            IsSnapToTickEnabled="True"
            TickFrequency="5" 
            TickPlacement="BottomRight"/>
    <TextBox Name="targetGrade"
             Grid.Row="3"
             Grid.Column="3"
             Width="30"
             Height="23"
             Text="{Binding ElementName=gradeSlider, Path=Value}"
             TextAlignment="Center"/>

However I'm struggling to include a label which will show display a different grade classification based on the slider's value range. I'd have thought that I could create the label:

<Label     Name="gradeClass"
           Grid.Row="2"
           Grid.Column="2"
           HorizontalAlignment="Center"
           VerticalAlignment="Bottom"/>

And then use code:

        string gradeText;

        if (gradeSlider.Value >= 40 && gradeSlider.Value < 50)
        {
            gradeText = "Pass";
            gradeClass.Content = gradeText;
        }
        else if (gradeSlider.Value >= 50 && gradeSlider.Value < 60)
        {
            gradeText = "2:2";
            gradeClass.Content = gradeText;
        }
        else
        {
            gradeText = "so on...";
            gradeClass.Content = gradeText;
        }

But the label just stays as "Pass" whatever the slider value. Could somebody please advise me as to where I'm going wrong? I tried using Content = "{Binding Source = gradeText}" on the Label xaml and removing the gradeClass.Content's in the code but it complained that gradeText was declared but never used. Many thanks to anyone who can help.

Upvotes: 3

Views: 3683

Answers (3)

Seekeer
Seekeer

Reputation: 1394

Simpliest way is to bind Label content to value of Slider and add converter, something like this:

<Label Name="gradeClass"
       Grid.Row="2"
       Grid.Column="2"
       Text="{Binding ElementName=gradeSlider, Path=Value, Converter={StaticResource SliderValueToTextConverter}}"
       HorizontalAlignment="Center"
       VerticalAlignment="Bottom"/>

There are several ways to define converter. For example, you can define it in host element resources, say you placed all this controls in window, then:

<Window.Resources>
    <convertors:SliderValueToTextConverter x:Key="SliderValueToTextConverter" />
</Window.Resources>

And converter is a class, which implement IValueConverter interface. Good articles about converters: http://www.wpftutorial.net/ValueConverters.html , http://www.dev102.com/2008/07/17/wpf-binding-converter-best-practices/

But as Yaur sad - the "true" way is to use MVVM pattern and not to bind between controls, but bind controls to ViewModel properties and then use converters.

Update: one great thread about converters: Should I declare converters in App.xaml or as a per-file resource?

Upvotes: 4

Yaur
Yaur

Reputation: 7452

The "right" way to do this is to bind them both to a "Grade" property on your ViewModel and add a ValueConverter to convert the numeric property to the desired text value on your label.

Upvotes: 3

Reza ArabQaeni
Reza ArabQaeni

Reputation: 4907

You can use binding on lable like TextBox and a Converter class to convert slider value to desire text.

public class SliderToTextConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        // Do the conversion from Slider.Value(int) to Text
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return null;
    }
}

Upvotes: 3

Related Questions