Note that there are some explanatory texts on larger screens.

plurals
  1. POIs this WPF ProgressBar Odd render behaviour a Bug?
    primarykey
    data
    text
    <p>Hope someone can help. I have a simple scenario where clicking checkboxes is driving a progress bar in <a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation" rel="nofollow noreferrer">WPF</a>. The checkboxes are contained in a UserControl and the Progress bar is in a simple WPF client window. On the user control I am using two dependency properties: 1) the existing Tag property has the value I wish to bind to the progress bar value and 2) a DP called CbCount which represents the total number of checkboxes.</p> <p><strong>The problem:</strong> When the application runs the progress bar's progress shows as being 100% complete even though via Snoop I can see the value is in fact 0. Clicking on the checkboxes everything works fine as expected.</p> <p>Code: UserControl - within namespace ProgBarChkBxs:</p> <pre><code>public partial class ucChkBoxes : UserControl { #region CbCount public static readonly DependencyProperty CbCountProperty = DependencyProperty.Register("CbCount", typeof(double), typeof(ucChkBoxes), new FrameworkPropertyMetadata((double)0)); /// &lt;summary&gt; /// Gets or sets the CbCount property. This dependency property /// indicates the number of checkBoxes /// &lt;/summary&gt; public double CbCount { get { return (double)GetValue(CbCountProperty); } private set { SetValue(CbCountProperty, value); } } #endregion double _totalCount = 0; double _numberChecked = 0; double DEFAULT = 0; public ucChkBoxes() { InitializeComponent(); this.Tag = DEFAULT; this.Loaded += new RoutedEventHandler(ucChkBoxes_Loaded); } void ucChkBoxes_Loaded(object sender, RoutedEventArgs e) { if (this.ourContainer.Children.Count != 0) { _totalCount = this.ourContainer.Children.Count; } this.CbCount = (double)_totalCount; } private void CheckBox_Checked(object sender, RoutedEventArgs e) { if (e.OriginalSource.GetType() == typeof(CheckBox)) { CheckBox cb = (CheckBox)e.OriginalSource; if (cb.IsChecked == true) { _numberChecked++; } if (cb.IsChecked != true) { _numberChecked--; } //simple POC progress metric this.Tag = (double)(_numberChecked / _totalCount * _totalCount); } } } </code></pre> <p>XAML:</p> <pre><code>&lt;UserControl x:Class="ProgBarChkBxs.ucChkBoxes" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="Auto" Width="Auto"&gt; &lt;StackPanel&gt; &lt;TextBlock Text="Please select options" &gt;&lt;/TextBlock&gt; &lt;StackPanel Name="ourContainer" CheckBox.Checked="CheckBox_Checked" CheckBox.Unchecked="CheckBox_Checked"&gt; &lt;CheckBox&gt;Fruit Juice&lt;/CheckBox&gt; &lt;CheckBox&gt;Coffee&lt;/CheckBox&gt; &lt;CheckBox&gt;Toast&lt;/CheckBox&gt; &lt;CheckBox&gt;Cereal&lt;/CheckBox&gt; &lt;CheckBox&gt;Grapefruit&lt;/CheckBox&gt; &lt;/StackPanel&gt; &lt;/StackPanel&gt; &lt;/UserControl&gt; </code></pre> <p>The Client which just has the databindings is a simple window - the local namespace below refers to the project namespace xmlns:local="clr-namespace:ProgBarChkBxs", the meat of the code is:</p> <pre><code>&lt;StackPanel&gt; &lt;local:ucChkBoxes x:Name="chkBoxes"/&gt; &lt;ProgressBar Name="pb" Background="Azure" Minimum="0" Height="30" Value="{Binding ElementName=chkBoxes,Path=Tag }" Maximum="{Binding ElementName=chkBoxes,Path=CbCount }" /&gt; &lt;/StackPanel&gt; </code></pre> <p>The really weird thing is if within the DP definition of the CbCount if I change the FrameworkPropertyMetadata to a really small value to say (double)0.001 the problem goes away.</p> <p>I am running this on XP.</p> <p>All help gratefully received - thanks.</p> <p><strong>Update:</strong> I have been digging into this again as it gnaws at my sole (who said get a life!)</p> <p>Things I did:</p> <p>1) Adding a slider which also like progressBar inherits from RangeBase gives me the expected behaviour.</p> <p>2) Spinning up reflector I can see the static ctor for ProgressBar sets the default value first to 100, RangeBase.MaximumProperty.OverrideMetadata(typeof(ProgressBar), new FrameworkPropertyMetadata(100.0)); Should AffectMeasure? whereas in the slider: RangeBase.MaximumProperty.OverrideMetadata(typeof(Slider), new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsMeasure));</p> <p>3) So we need another layout pass after a I set the ProgressBar.Value Going back to my simple POC application if within a the progressBar loaded handler in the client window I jig the layout on the first run through:</p> <pre><code>this.Width += 1; //trigger another layout pass </code></pre> <p>Then, hey, presto it works.</p> <p><strong>So is this a bug?</strong></p> <p>I still do not fully understand though how the progressBar value which is calculated from Minimum and Maximum values is affected in this way and not the Slider - the default value of Maximum appears to be having an effect and it looks as if the ProgressBar default should affect the measure pass. (missing <code>FrameworkPropertyMetadataOptions.AffectsMeasure</code>.)</p> <p><strong>Can anyone help, either confirm my thinking or explain what is really happening here?</strong></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload