1

I have a WPF project and am using ProgressBars in a ListBox to display a series of values. I want to display the numeric value in a textbox positioned just above the progress bar. How can I get the position of each progress bar's Value so I can then place a TextBox? This is the ProgressBar xaml:

<ProgressBar Orientation="Vertical" 
                          Width="78"
                          BorderThickness="0"
                          Minimum="{Binding minTest}"
                          Maximum="{Binding maxTest}"
                          Value="{Binding valTest}"
                          Background="Transparent"
                          Foreground="{Binding bar_color}"/>
H.B.
  • 166,899
  • 29
  • 327
  • 400
user94639
  • 37
  • 1
  • 7
  • You mean the X position on the screen of where the bar is at? That's just (value * width) / (max - min), no? – SledgeHammer Jan 19 '17 at 18:37
  • Are you asking for the percentage traveled between min and max? (also calculable) – BradleyDotNET Jan 19 '17 at 19:17
  • Yes, the X position on the screen of where the progress bar is located, between min and max. I was thinking there might be a property I could query but I can calculate it as well. Thanks. – user94639 Jan 23 '17 at 19:11

2 Answers2

2

There are several ways to do it. One could be:

    <Window x:Class="SO41749207.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SO41749207"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
  <Window.Resources>
    <Style TargetType="ListBoxItem">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem">
            <StackPanel Orientation="Vertical">
              <TextBox Text="{Binding ElementName=MyProgress, Path=Value}" />
              <ProgressBar Name="MyProgress" Value="50" />
            </StackPanel>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Window.Resources>
  <Grid>
    <ListBox>
      <ListBoxItem>a</ListBoxItem>
      <ListBoxItem>b</ListBoxItem>
      <ListBoxItem>c</ListBoxItem>
    </ListBox>
  </Grid>
</Window>

A more MVVM-like approach is to define a view model for the list items:

  public class MyListItem : INotifyPropertyChanged
  {

    double m_progressValue = 0.0;
    public double ProgressValue
    {
      get { return m_progressValue; }
      set
      {
        m_progressValue = value;
        OnPropertyChanged("ProgressValue");
      }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string property)
    {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
  }

... and a corresponding DataTemplate:

<DataTemplate DataType="{x:Type models:MyListItem}">
  <StackPanel Orientation="Vertical">
    <TextBox Text="{Binding ProgressValue}" HorizontalAlignment="Center" Width="50" TextAlignment="Center" />
    <ProgressBar Value="{Binding ProgressValue}" />
  </StackPanel>
</DataTemplate>

... for the list items:

<ListBox HorizontalContentAlignment="Stretch">
  <ListBox.ItemsSource>
    <cols:ArrayList>
      <models:MyListItem ProgressValue="10" />
      <models:MyListItem ProgressValue="50" />
      <models:MyListItem ProgressValue="80" />
    </cols:ArrayList>
  </ListBox.ItemsSource>
</ListBox>
0

Since you are already binding the ProgressBar Value to your viewmodel:

<ProgressBar Orientation="Vertical" 
                      Width="78"
                      BorderThickness="0"
                      Minimum="{Binding minTest}"
                      Maximum="{Binding maxTest}"
                      Value="{Binding valTest}"
                      Background="Transparent"
                      Foreground="{Binding bar_color}"/>

why not bind the TextBox to the same value?

<TextBox Text="{Binding valTest}" />
Eric
  • 1,737
  • 1
  • 13
  • 17
  • This suggestion sets the value of the text, but what I am trying to do is set the position of the textbox. – user94639 Dec 06 '17 at 22:04