Reputation: 14034
I want to update the UI while loading some long work. What I want is when the data is loading I want to show an UserControl
which is nothing but a wait message. I have tried BackgroundWorker
, Dispatcher.BeginInvoke
and ThreadPool.QueueUserWorkItem
but I dont know why it is not doing as per the expectation. Please help
Dispatcher.BeginInvoke(new Action(() => img.Visibility = Visibility.Visible));
//Load some long wok here
Dispatcher.BeginInvoke(new Action(() => img.Visibility = Visibility.Collapsed), DispatcherPriority.Background);
What I am looking for is to show an Image while loading and when load finish it must be collapsed.
Edit:
<Grid Grid.Column="2"
Name="DetailsPane">
<Grid.Background>
<ImageBrush ImageSource="img/back.jpg"
Stretch="UniformToFill" />
</Grid.Background>
<Image Name="img"
Margin="5"
Stretch="None"
Visibility="Collapsed"
Source="img/Loading.png" />
</Grid>
I have a Image to show while a loading is going on the Listbox SelectionChanged. So inside the SelectionChanged Event I'll be loading a detailed info in the Grid Called DetailsPane of a particular thing Cliked on the ListBox. While the loading of the info takes place how should I be showing this image on the DetailsPane?
Reached till here
Created a Dependency Property called State of type bool, then
private void LstAllFeatures_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
State = false;
// Loading Heavy Work
State = true;
}
<Image Name="img"
Margin="5"
Stretch="None">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Visibility"
Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding State}"
Value="False">
<Setter Property="Visibility"
Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
In DeatilsPane.Children
-> _visualChildren
-> InternalArray[0]
is a Image. When open that in the WPF Visualizer Shows the Image Visibility = Visible but it doesn't show. Any Light on it please.
Upvotes: 0
Views: 1752
Reputation: 46
first userControl must implement INotifyPropertyChanged like:
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
then State must definition like:
public bool _state;
public bool State
{
get { return _state; }
set
{
if (value != _state)
{
_state= value;
RaisePropertyChanged();
}
}
}
then in code where you want call LongWork()
State = true;
await Task.Run(()=>LongWork());
State = fasle;
then in xaml you write like:
<Image Margin="5"
Stretch="None">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Visibility"
Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding State,RelativeSource= {RelativeSource AncestorType={x:Type test:UserControlName}},Mode=TwoWay}"
Value="False">
<Setter Property="Visibility"
Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
Upvotes: 2
Reputation: 69959
Add a bool
property:
public bool IsLoading
{
get { return isLoading; }
set { isLoading = value; NotifyPropertyChanged("IsLoading"); }
}
Data bind it to the Image.Visibility
property:
<Image Margin="5" Stretch="None" Source="img/Loading.png">
<Image .Style>
<Style>
<Setter Property="Control.Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoading}" Value="True">
<Setter Property="Control.Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
Set it to true
when you start your long running task on a background thread:
IsLoading = true;
Set it to false
when your long running process is complete:
IsLoading = false;
Note that this will only work if you run your long running process on a background thread, otherwise, the UI thread will be busy and not update.
Upvotes: 0