tags:

views:

277

answers:

1

I have a slider and a label control. The text is displayed in the label (few paragraphs).

  1. I need to show only 3 words at a time.Every 1 second, move to the next set of 3 words.
  2. The slider is used to select the number of words that can be seen at once. So a user can increase it to say 10 and now every 1 second, a set of 10 words need to be displayed.

How would I achieve this behavior in WPF? I know I need to do some kind of databinding between the slider and a label, but not sure how to get the effect of (1) or (2).

Any help is appreciated!

A: 

Here is how I would solve it without using my {edf:ExpressionBinding} feature (which, alas, is not yet publically available):

Step 1: Create three DependencyProperties (not traditional NET properties) in your class:

 Text
 WordsPerGroup
 GroupToShow

Step 2: Bind the Slider to the "WordsPerGroup" property:

 <Slider ... Value="{Binding WordsPerGroups}" />

Step 3: Create an animation using a LinearInt32KeyFrame to animate the "GroupToShow" property that counts once per second and lasts as long as you like, for example this lasts 1 hour and counts to 3600:

 <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="GroupToShow" ...>
   <LinearInt32KeyFrame KeyTime="01:00:00" Value="3600" />
 <Int32AnimationUsingKeyFrames>

Step 4: Create a Converter that takes "Text", "GroupToShow" and "WordsPerGroup" and returns the text to display:

public SelectWordsConverter : IMultiValueConverter
{
  public object ConvertTo(object [] values, ...)
  {
    string text = values[0] as string;
    int groupToShow = values[1] as int;
    int wordsPerGroup = values[2] as int;  // maybe double, depending on slider binding

    return
      string.Join(" ",
        text
         .Split(" ", StringSplitOptions.RemoveEmptyEntries)
         .Skip(groupToShow * wordsPerGroup)
         .Take(wordsPerGroup)
      );
   }
   ...

Step 5: Use a MultiBinding to bind the TextBlock's Text property using your converter:

<TextBlock ...>
  <TextBlock.Text>
    <MultiBinding Converter="{x:Static local:SelectWordsConverter.Instance}">
      <Binding Path="Text" />
      <Binding Path="GroupToShow" />
      <Binding Path="WordsPerGroup" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

Step 6: Make sure you start your animation on load, or whenever you want the animation to start moving.

Step 7: (optional) Add a PropertyChangedCallback to "GroupToShow" to detect when the words have all been shown and do something appropriate (like start over, or stop the animation).

Ray Burns
Thanks! I guess I was barking up the wrong tree. I was looking to implement this using multithreading in which as user moves the slider, the thread would do a BeginInvoke to update the UI. This appears to be a diff way of doing it. Any help on where I can read up on this stuff?
A book to refer to is Adam Nathan's book Windows Presentation Foundation Unleashed. Read it cover to cover. There are also many blogs and questions on StackOverflow that can give you ideas. Download some WPF applications and libraries with source code and see how they do things. Look at the built-in Templates to see how they work (use Reflector with the BamlViewer add-in). Those would be my recommendations.
Ray Burns
Hey.. forgot to ask.. is the slider related code missing?
You'll need to fill in your desired MinValue and MaxValue for the slider, and perhaps some other settings depending on how you want it to look. That's what the "..." in Step 2 was intended to represent.
Ray Burns