I'm trying to implement a progress bar to monitor the downloading of content in a HttpWebRequest. I have never done databinding with XAML before, can anyone please give me tips on how I can set the Maximum value of the progress bar to the file size and the Value to the size of the content downloaded.
Thanks!
This XAML:
<ProgressBar Value="{Binding DownloadProgress, Mode=OneWay}" Minimum="0" Maximum="{Binding DownloadSize, Mode=OneWay}" IsHitTestVisible="False" />
should do it.
Beware of this SL bug however. Make sure Maximum binding appears before the Value binding in the XAML.
Related
I'm trying to bind the header text of aGroupBox to a property and display it using StringFormat.
The first part works and it returns the text as expected. But I want the final text to be formatted. For example when I return cm I want it to be displayed as Foundation Height (cm), but the code below only shows cm.
<GroupBox Header="{Binding CurrentTargetUnit,
Converter={StaticResource QuantityToTextConverter},
ConverterParameter={x:Static enumerations:Quantity.Length},
StringFormat='Foundation Height ({0})'}">
</GroupBox>
Try without quotes
....
StringFormat=Foundation Height ({0})}">
UPDATE
As you have used binding for header you should use HeaderStringFormatinstead.
....
HeaderStringFormat=Foundation Height ({0})}">
Read the documentation for more
I had the same issue. I found my answer here.
<GroupBox>
<GroupBox.Header>
<TextBlock Text="{Binding CurrentTargetUnit,
Converter={StaticResource QuantityToTextConverter},
ConverterParameter={x:Static enumerations:Quantity.Length},
StringFormat=Foundation Height ({0})}">
</GroupBox.Header>
</GroupBox>
You also need to remove the quotes from the StringFormat. Also, in the link above, it shows placing "{}" before anything in the StringFormat. If I recall correctly, you only need that if the place holder is first: StringFormat={}{0:C}
There are a limited amount of elements that will allow StringFormat Binding, TextBlock being one and GroupBox headers do not.
Try this instead:
StringFormat={}Foundation Height ({0})}">
I have a Telerik RadTimeBar in my XAML, I could easily customize whatever I wanted except the interval label placement. In the telerik demos intervals are somehow drawn inside the actual time bar, not on top of that. Here's a snapshot demonstrating it. I need to position day intervals the way Weeks are displayed here:
Whatever I do, I keep getting this rendered on the screen:
Here's my XAML:
<telerik:RadTimeBar Grid.Row="2" x:Name="multiDayTimeBar"
PeriodStart="{Binding TimeBarRangeStart}"
PeriodEnd="{Binding TimeBarRangeEnd}"
SelectionChanged="multiDayTimeBar_SelectionChanged"
SelectionStart="{Binding TimeBarSelectedStart, Mode=TwoWay}"
SelectionEnd="{Binding TimeBarSelectedEnd, Mode=TwoWay}"
ScrollMode="None"
HorizontalAlignment="Stretch">
<telerik:RadTimeBar.Intervals>
<telerik:DayInterval />
<telerik:HourInterval/>
</telerik:RadTimeBar.Intervals>
<telerik:RadLinearSparkline Margin="0,3"
LineStroke="#FF767676"
ItemsSource="{Binding TimeBarSource}"
XValuePath="Timestamp"
YValuePath="DemandValue" />
</telerik:RadTimeBar>
Digging through the API documentation didn't help. Telerik's demo codes do not hint something either. If someone had a similar problem, any advice would be appreciated.
Thank you.
I have the WPF UI demos installed on my computer. After taking a look at the TimeBar example they give this code:
<telerik:RadTimeBar Name="timeBar1" Height="150"
PeriodStart="{Binding PeriodStart, Mode=TwoWay}"
PeriodEnd="{Binding PeriodEnd, Mode=TwoWay}"
VisiblePeriodStart="{Binding VisiblePeriodStart, Mode=TwoWay}"
VisiblePeriodEnd="{Binding VisiblePeriodEnd, Mode=TwoWay}"
SelectionStart="{Binding SelectedStartDate, Mode=TwoWay}"
SelectionEnd="{Binding SelectedEndDate, Mode=TwoWay}"
MinSelectionRange="{Binding MinSelectionRange, Mode=TwoWay}"
IsSnapToIntervalEnabled="True">
<telerik:RadTimeBar.Intervals>
<telerik:QuarterInterval />
<telerik:MonthInterval />
<telerik:WeekInterval />
<telerik:DayInterval />
<telerik:HourInterval/>
</telerik:RadTimeBar.Intervals>
<telerik:RadLinearSparkline LineStroke="#FF767676" ItemsSource="{Binding ServerInfos}" XValuePath="Date" YValuePath="UniqueVisitors" />
</telerik:RadTimeBar>
Which they say produces this time bar:
Not sure if this will help you or not, but the only thing that I could see that was different is that they set the IsSnapToIntervalEnabled="True" the VisiblePeriodStart and the VisiblePeriodEnd. Think these might need to be set?
In my WPF app we are using an adorner for displaying validation messages, in the particular case there is a single row grid that has multiple controls some of which have validation. The problem I'm having is that I want to force the width of the error message control to be the same as the grid but can't seem to find a way to reference that grid from the adorner template. Here is a sample of what I tried:
<ControlTemplate x:Key="Local_TopAdornedTemplateWide">
<StackPanel>
<AdornedElementPlaceholder x:Name="adornedElement"/>
<TextBlock MaxWidth="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType=Grid}, ElementName=adornedElement}"
TextWrapping="Wrap"
Text="{Binding Converter={StaticResource Local_ValidationErrorMessageConverter}}"
Style="{DynamicResource Error_Text}"
Padding="2 1 0 0"
Visibility="{Binding ElementName=adornedElement, Mode=OneWay, Path=AdornedElement.IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"
/>
</StackPanel>
</ControlTemplate>
This causes the application to crash with an XamlParseException.
Ideally the solution would not be specific to a grid so that it would get the width of any container type, but for now grid is the only use case.
Edit:
Here is an example of another template we use in the application; this template would not work for my case as it would limit the error to be the width of a single column of the aforementioned grid:
<ControlTemplate x:Key="Local_TopAdornedErrorTemplate">
<StackPanel>
<AdornedElementPlaceholder x:Name="adornedElement"/>
<TextBlock MaxWidth="{Binding ElementName=adornedElement, Path=ActualWidth}"
TextWrapping="Wrap"
Text="{Binding Converter={StaticResource Local_ValidationErrorMessageConverter}}"
Style="{DynamicResource Error_Text}"
Padding="2 1 0 0"
Visibility="{Binding ElementName=adornedElement, Mode=OneWay, Path=AdornedElement.IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"
/>
</StackPanel>
</ControlTemplate>
Using snoop I captured the following two screenshots (I could not take one of the full stack to prevent posting anything proprietary)
This shot shows the grid I mentioned previously, within this it is the FinancialTextBox item that is being adorned
This shot shows two things, the item selected in blue is the highest ancestor of the grid in the previous shot, the yellow highlight is the Textbox from the content template
With those two it seems to be apparent that (based on information from Contango's answer) the two items aren't not in the same visual tree which would lead me to believe my question is not possible. However the second template I added (which does work) points that at least some visual information from the adorned element lives on in the place holder.
So now my question boils down to a) does this information include the parent of the adorned element and b) how can this be accessed via a binding on a different element?
This ended up being a lot simpler than the path I was trying to go down.
I was doing some reading on the AdornedElementPlaceholder class and came across this entry on MSDN and noticed that the class actually has a property called parent, with that I tried the following binding and it works perfectly:
MaxWidth="{Binding ElementName=adornedElement,
Mode=OneWay,
Path=AdornedElement.Parent.ActualWidth}"
WPF is quite powerful and flexible.
You can bind any property in any XAML tag to any property in any other XAML tag.
For example, you could write a test app that binds the Text property of an input box to the Text property of a label, so as you type something into the text box, the label would change automatically (assuming you use UpdateSourceTrigger=PropertyChanged). This is a direct XAML to XAML binding, with no C# in sight.
Similarly, you could bind the width of your error box to the width of the parent control, whatever that may be.
Google RelativeSource and AncestorType, this is a great link:
http://druss.co/2013/10/wpf-binding-examples/
See if you can grok how the Visual Tree and Logical Tree works in WPF, once you understand that, you will understand more of how binding works.
I'd also recommend using the free tool Snoop to look at the Visual Tree. XAML Spy is excellent, but not free.
Snoop can tell you if there is anything that has a bad binding at runtime (you set the filters up, and it will list all bad bindings).
You can use Snoop to get the full XAML path of your source (the XAML you wrote above), then get the full XAML path of the target (i.e. the ActualWidth of your Grid), then compare them: it may be quickly apparent that one is not the ancestor of the other, as they are on different branches of the visual tree, or that there is some other issue which is preventing a simple walk up the visual tree from working.
If you just want to get something working, as a proof of concept, try naming the target XAML grid using x:Name, and reference it by name instead of AncestorType.
I'm developing an application using C# and XAML and I've encountered a problem that is confusing me. I have a property in my data called GroupImage and have used binding to set the Source property of an Image with it. That worked fine but when I wanted to do the same thing a second time it doesn't show the image in the second Image control.
<Image Source="{Binding Group.GroupImage}" Width="250" Height="500" Stretch="UniformToFill" />
<Image VerticalAlignment="Bottom" Stretch="UniformToFill" Source="{Binding Group.GroupImage}" Grid.RowSpan="2"/>
The top one works fine the bottom one doesn't. I have been reading about Data Binding and have gotten the impression that you need to specify something in the DataContext to use a property more than once. Is this right? It seems a very strange way of doing this.
I am relatively new to C# so sorry if I'm missing something obvious. I'd appreciate a more knowledgeable cluing me in.
Thanks
Update Following the assistance I received I figured out that the context was being set to
DataContext="{Binding Group}"
And as a result my second line needed to change to the following since the Data Context was already set to Group.
<Image VerticalAlignment="Bottom" Stretch="UniformToFill" Source="{Binding GroupImage}" Grid.RowSpan="2"/>
You don't need to specify something in the DataContext to use a property more than once. But your two Image have to have the right DataContext (you can easily test it with the debugger), depending on their location on the visual tree (You didn't provide any code for the DataContext part ?) .
You can also check that your Image's Width/Height are not 0.
I am trying to use the ProgressBar as a representation of a percent value (I have not found an alternative control that looks right).
I am trying to set the value. It is my understanding that just setting the Value property should work, and update the control when my current event handler ends and control passes back to the UI.But no matter what I set the value to, the bar stays empty.
Here is my XAML:
<ProgressBar Name="LevelProgress" Maximum="100" Minimum="0" />
and my C#:
LevelProgress.Value = 43.0;
I have also tried:
LevelProgress.SetValue(ProgressBar.ValueProperty,43.0);
Even setting the Value property in the XAML definition does not work.
I really don't want to have to setup some big background thread thing just to set this value. Can anyone recommend a solution, or an alternative control?
Works for me
Do you
InitializeComponent();
Before?
LevelProgress.Value = 43.0;
I put it in the Loaded event and it worked there.
And I tried
<ProgressBar Name="LevelProgress" Maximum="100" Minimum="0" Value="43" />
And it works there. Something is wrong with the progress bar.