Reputation: 15
I'm having a problem with binding values to controls. I checked in other windows I have and I think I'm doing it the same way. I want to show something like loading window from App before main window will open. The problem is nothing is changing (text/content/value of controls).
InitizalizationWindow:
public InitializationWindow()
{
...
InitializationWindowClass.Progress = new InitializationWindowClass();
this.mainSP.DataContext = InitializationWindowClass.Progress;
}
and part of xaml:
<StackPanel Name="mainSP" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="0, 0, 0, 10">
<TextBlock x:Name="tblProgress" FontSize="14" Text="{Binding ProgressText}" TextAlignment="Center" TextWrapping="Wrap" />
<Grid>
<telerik:RadProgressBar x:Name="progress" Value="{Binding ProgressValue}" telerik:StyleManager.Theme="Summer" Height="25" IsIndeterminate="False" />
<Label x:Name="lblPercent" FontWeight="Bold" Content="{Binding ProgressValueString}" HorizontalAlignment="Center" VerticalContentAlignment="Center" />
</Grid>
</StackPanel>
InitializationWindowClass:
public class InitializationWindowClass : INotifyPropertyChanged
{
public static InitializationWindowClass Progress { get; set; }
private string progressText = String.Empty, progressValueString = String.Empty;
private int progressValue = 0;
public event PropertyChangedEventHandler PropertyChanged;
public string ProgressText
{
get
{
return progressText;
}
set
{
progressText = value;
NotifyPropertyChanged("ProgressText");
}
}
public string ProgressValueString
{
get
{
return progressValueString;
}
set
{
progressValueString = value;
NotifyPropertyChanged("ProgressValueString");
}
}
public int ProgressValue
{
get
{
return progressValue;
}
set
{
progressValue = value;
ProgressValueString = String.Format("{0}%", progressValue);
NotifyPropertyChanged("ProgressValue");
NotifyPropertyChanged("ProgressValueString");
}
}
private void NotifyPropertyChanged(String propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
and part of App.xaml.cs:
protected override void OnStartup(StartupEventArgs e)
{
InitializationWindow iw = new InitializationWindow();
iw.Show();
InitializationWindowClass.Progress.ProgressValue = Convert.ToInt32(((decimal)count / (decimal)sum) * 100);
InitializationWindowClass.Progress.ProgressText = "Some text";
...
...
InitializationWindowClass.Progress.ProgressValue = Convert.ToInt32(((decimal)count / (decimal)sum) * 100);
InitializationWindowClass.Progress.ProgressText = "New text";
...
...
}
I checked and when I'm changing i.e. ProgressValue from App.xaml.cs, the value is changing - going to
get
{
return progressValue;
}
So the question is - what I'm doing wrong?
Upvotes: 0
Views: 119
Reputation: 5373
What you are doing won't work. You are displaying your splash screen and performing load operations on the same thread. This way, while your loading operations run, the main UI thread is busy and is not updating, even if the data in the background are changing properly. That's why you are probably seing "wait" cursor, your splash window is unresponsive, and your main window may not even appear at all.
Here you have a nice example of working SplashScreen in wpf
Upvotes: 0
Reputation: 5421
This is a threading issue. Binding changes are posted to the Dispatcher, and then the UI thread pulls those events out of the Dispatcher queue and processes them.
Here you are making changes to the bindings in the OnStartup
event, which itself is being handled by the UI thread. This means that those binding changes won't be handled until the OnStartup
event is exited. What you probably end-up seeing in your user interface is just the values of those progress properties when they were last changed.
What you need to do is move the progress reporting to another thread. In other words, shift the work currently done in the OnStartup
event to a different thread, using async
/await
or some other threading mechanism.
Original, incorrect answer follows:
ProgressText
, ProgressValueString
and ProgressValue
are all properties on InitializationWindowClass
, not InitializationWindow
. It looks like you need to either set the DataContext
on the StackPanel
to point at the Progress
property of the InitializationWindow
, or include the Progress
property as part of the binding path for the individual elements.
That is, either this:
<StackPanel ... DataContext="{Binding Progress}">
... rest the same ...
</StackPanel>
or this:
<StackPanel ...>
<TextBlock ... Text="{Binding Progress.ProgressText}" ... />
<Grid>
<telerik:RadProgressBar ... Value="{Binding Progress.ProgressValue}" ... />
<Label ... Content="{Binding Progress.ProgressValueString}" ... />
</Grid>
</StackPanel>
Upvotes: 1