My goal is to update the progress bar while another set of script (calculations) is running.
I have followed the sample files from here and tried to bind it to my MVVM script but the progress bar would not update.
Here is the Progressbar script
In the script below, I have included progressBarCounter and noOfDataas a value in another script that is calculated in a method.
Proof that data is updated
public partial class ProgressBarTaskOnWorkerThread : Window
{
public ProgressBarTaskOnWorkerThread()
{
InitializeComponent();
}
private void Window_ContentRendered(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
EtabsDataFormatting.ViewModel.SpliceViewModel data = new EtabsDataFormatting.ViewModel.SpliceViewModel();
for (int i = data.progressBarCounter; i < data.noOfData;)
{
(sender as BackgroundWorker).ReportProgress(i);
}
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pbStatus.Value = e.ProgressPercentage;
int perc = Convert.ToInt32(pbStatus.Value);
UpdateProgress(perc);
}
public void UpdateProgress(int percentage)
{
pbStatus.Value = percentage;
if (percentage == 100)
{
Close();
}
}
}
Here is part of my XAML code for the button to start calculations and run the progressbar
The command Binding = RunCalcBtn is bound to the calculation scripts, therefore, I have created a click to run the progress bar instead.
<Button x:Name = "ApplyButton" Margin="0 1 0 1" Content ="Start Calculation" Command="{Binding RunCalcBtn, Mode=TwoWay}" Click ="PrgBar_Click"/>
Progressbar XAML.cs button click
This part displays the progress bar, but it does not update.
private void PrgBar_Click(object sender, RoutedEventArgs e)
{
ProgressBar.ProgressBarTaskOnWorkerThread progressWindow = new ProgressBar.ProgressBarTaskOnWorkerThread();
progressWindow.Show();
}
Thank you so much for helping me in advance!
As Flithor has said, the best way to achieve this is with Progress<T>.
I give a short illustration of how to use this.
Firstly you need to create a Property in your View Model so that you can bind the ProgressBar's Value to something. Your ViewModel will need to implement INotifyPropertyChanged so that the Property set can invoke RaisePropertyChangedEvent.
Next create a Progress inside the method called by the Button click and pass it to your worker method. Use an ICommand for this, so that it can be bound to your Button (you don't need the Click event). Something like this:
var progress = new Progress<int>(percent =>
{
ProgressProperty = percent;
});
await Task.Run(() => myWorker(progress));
Finally within your worker method you periodically update the value like this:
private void myWorker(IProgress<int> progress)
{
progress.Report(1);
// ...
progress.Report(100);
}
By way of explanation: I used an integer, but you can also use a double if you want really fine calculations! The constructor of the Progress object takes the ProgressProperty (the name I gave to the property that gets bound to the ProgressBar) as a parameter. This means that when the worker calls Report(), the ProgressProperty is automatically updated with the new value, and hence can be reflected in the UI. Finally your worker method is invoked with await so that the UI is able to update on every incremented value.
For a very full explanation on Progress, see Stephen Cleary's blog
In MVVM WPF, you should do this to take full advantage of it:
View:
<Grid>
<ProgressBar Name="myProgressBar"
Minimum="0"
Value="{Binding ProgressBarValue,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
Maximum="100"
Foreground="{Binding ColorState,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
Background="#424242"
BorderBrush="Transparent"
BorderThickness="0"/>
<TextBlock Text="{Binding ElementName=myProgressBar, Path=Value,Mode=OneWay,UpdateSourceTrigger=PropertyChanged, StringFormat={}{0:0}%}"
FontWeight="DemiBold"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
ViewModel:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Threading;
namespace YourNameSpace.Models
{
public class Device : INotifyPropertyChanged
{
public Device()
{
this.ProgressBarValue = 50; // Your ProgressBar Foreground will be "GREEN" automatically
// This is the
}
private double progressBarValue;
public double ProgressBarValue
{
get { return progressBarValue; }
set
{
progressBarValue = value;
if(progressBarValue < 50)
this.ColorState = "Red";
else if (progressBarValue >= 50)
this.ColorState = "Green";
NotifyPropertyChanged("ProgressBarValue");
}
}
private string colorState = "Transparent";
public string ColorState
{
get { return colorState; }
set { colorState = value; NotifyPropertyChanged("ColorState"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string Obj)
{
if (PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(Obj));
}
}
}
}
You can REMOVE this from your code:
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pbStatus.Value = e.ProgressPercentage;
int perc = Convert.ToInt32(pbStatus.Value);
UpdateProgress(perc);
}
public void UpdateProgress(int percentage)
{
pbStatus.Value = percentage;
if (percentage == 100)
{
Close();
}
}
And ONLY use this:
for (int i = data.progressBarCounter; i < 100; i++)
{
ProgressBarValue = i;
}
Your
ProgressBar Value
Progress Foreground Color
will be updated automatically.
Related
I have a screen which used to check connection with multiple devices by COM/USB Port as the below picture
https://i.stack.imgur.com/CAjK0.png
When user click button Check Device if checking a device connection is finished, icon good or not good will display next to combobox and progress bar will update value based on total of devices. For example, there are 4 devices then progress bar will update 25%, 50%, 75%, 100% after checking.
I tried to use PropertyChanged to update value but it's seem not working. After clicking button, the progress bar is visible but value is always 100. Please help me with this!
Here is my code:
File xaml:
<ProgressBar x:Name="pgProcessing" Visibility="Collapsed" Minimum="0" Maximum="100" Value ="{Binding Percent, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
Code behind:
private double _percent;
public double Percent
{
get { return _percent; }
set { _percent = value; OnPropertyChanged("Percent"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private void BtnCheck_Click(object sender, RoutedEventArgs e)
{
pgProcessing.Visibility = Visibility.Visible;
_percent = 0;
this.Percent = _percent;
// Do check connection 1st device
// End
_percent = (100 * currentDevice) / TOTAL_DEVICE;
this.Percent = _percent; //50%
// Do check connection 2nd device
// End
_percent = (100 * currentDevice) / TOTAL_DEVICE;
this.Percent = _percent; //100%
}
My constructor:
public HealthCheck()
{
InitializeComponent();
this.DataContext = this;
}
I also implement INotifyPropertyChanged in the cs file
Seems you are confusing how the Binding works. My recommendation would be to use MVVM pattern and not mix stuff up (if possible). To solve you problem there are two ways. First let the code behind remain code behind. All you need is to assign the Value directly to the progress bar like this:
private async void Button_Click(object sender, RoutedEventArgs e)
{
pgProcessing.Visibility = Visibility.Visible;
pgProcessing.Value = 0;
await Task.Delay(100);
pgProcessing.Value = 25;
await Task.Delay(100);
pgProcessing.Value = 50;
await Task.Delay(100);
pgProcessing.Value = 75;
await Task.Delay(100);
pgProcessing.Value = 100;
}
However if you would like to use MVVM, I you can call the property changes on the model via code behind as well. Example :
public class Model : INotifyPropertyChanged
{
private double _percent;
public double Percent
{
get { return _percent; }
set { _percent = value; OnPropertyChanged("Percent"); }
}
public event PropertyChangedEventHandler? PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
and your *xaml.cs :
public partial class MainWindow : Window
{
readonly Model _model;
public MainWindow()
{
InitializeComponent();
_model = new Model();
DataContext = _model;
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
pgProcessing.Visibility = Visibility.Visible;
_model.Percent = 0;
await Task.Delay(100);
_model.Percent = 25;
await Task.Delay(100);
_model.Percent = 50;
await Task.Delay(100);
_model.Percent = 75;
await Task.Delay(100);
_model.Percent = 100;
}
}
Regardless, I suggest to implement Icommand/relayCommand pattern into your ViewModel as well and proccess button press also within View Model.
In my Main() WPF program I run a time consuming method asynchronously. When this method is running, I fire up a secondary window that contains a ProgressBar, which I update using IProgress.
Following is an example of my setup.
MAIN Program:
public partial class MainWindow : Window
{
private ProgressBarWindow pbwWindow = null;
public MainWindow()
{
InitializeComponent();
}
private void RunMethodAsync(IProgress<int> progress)
{
Dispatcher.Invoke(() =>
{
pbwWindow = new ProgressBarWindow("Processing...");
pbwWindow.Owner = this;
pbwWindow.Show();
});
TimeConsumingMethod(progress);
}
private void TimeConsumingMethod(IProgress<int> progress)
{
for (int i = 1; i <= 100; i++)
{
// Thread.Sleep() represents actual time consuming work being done.
Thread.Sleep(100);
progress.Report(i);
}
}
private async void btnRun_Click(object sender, RoutedEventArgs e)
{
IProgress<int> progress;
progress = new Progress<int>(i => pbwWindow.SetProgressUpdate(i));
await Task.Run(() => RunMethodAsync(progress));
}
}
My ProgressBarWindow which contains the progress bar looks like this:
public partial class ProgressBarWindow : Window
{
Stopwatch stopwatch = new Stopwatch();
BackgroundWorker worker = new BackgroundWorker();
public string ElapsedTimeString { get; set; }
public ProgressBarWindow(string infoText)
{
InitializeComponent();
SetTimer();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
StartTimer();
}
private void SetTimer()
{
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += (s, e) =>
{
while (!worker.CancellationPending)
{
worker.ReportProgress(0, stopwatch.Elapsed);
Thread.Sleep(1000);
}
};
worker.ProgressChanged += (s, e) =>
{
TimeSpan elapsedTime = (TimeSpan)e.UserState;
ElapsedTimeString = string.Format("{0}:{1}:{2}", elapsedTime.Minutes, elapsedTime.Seconds, elapsedTime.Milliseconds);
};
}
private void StartTimer()
{
stopwatch.Start();
worker.RunWorkerAsync();
}
private void StopTimer()
{
stopwatch.Stop();
worker.CancelAsync();
}
public void SetProgressUpdate(int progress)
{
pbLoad.Value = progress;
if (progress >= 100)
{
StopTimer();
Close();
}
}
}
I borrowed the StopWatch logic from this SO answer.
Then, on my ProgressBarWindow I have a TextBlock which I've used Binding as follows, just as the answer above says.
<TextBlock Name="tbElapsedTime" Text="{Binding ElapsedTimeString}"/>
Now when I run the program, the method executes, and the progress bar updates just fine. However, my TextBlock that's supposed to update with the elapsed time does not get updated.
To verify my timer's running fine, I updated TextBlock value directly as follows instead of Binding and it worked as expected and displayed Elapsed Time:
worker.ProgressChanged += (s, e) =>
{
TimeSpan elapsedTime = (TimeSpan)e.UserState;
ElapsedTimeString = string.Format("{0}:{1}:{2}", elapsedTime.Minutes, elapsedTime.Seconds, elapsedTime.Milliseconds);
tbElapsedTime.Text = ElapsedTimeString;
};
So I'm guessing my problem is with the Binding and possibly using BackgroundWorker on a windows that's already being run asynchronously? How could I fix this so I could use DataBinding?
As mentioned by Ginger Ninja, you have to implement INotifyPropertyChanged and use RelativeSource={RelativeSource Self} (as additional setting to the binding):
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _ElapsedTimeString;
public string ElapsedTimeString
{
get { return _ElapsedTimeString; }
set
{
if (_ElapsedTimeString != value)
{
_ElapsedTimeString = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ElapsedTimeString"));
}
}
}
// ....
}
and the XAML:
<TextBlock Name="tbElapsedTime" Text="{Binding ElapsedTimeString, RelativeSource={RelativeSource Self}}"/>
Data binding is often used in combination with MVVM. That is IMHO the prefered way to solve your problem... If you want to use MVVM, you have to implement a view model that contains all the logic and implements INotifyPropertyChanged. Than you can simply bind properties from the view model to the view. That ensures a nice separation between (GUI related) logic and view.
I have a WPF application which is built on the MVVM design pattern.
I wish to implement a progress bar in the app, that follows the MVVM pattern.
Does any one have any suggestions on how to implement this?
Thanks in advance
Typically your UI would simply bind to properties in your VM:
<ProgressBar Value="{Binding CurrentProgress, Mode=OneWay}"
Visibility="{Binding ProgressVisibility}"/>
Your VM would use a BackgroundWorker to do the work on a background thread, and to periodically update the CurrentProgress value. Something like this:
public class MyViewModel : ViewModel
{
private readonly BackgroundWorker worker;
private readonly ICommand instigateWorkCommand;
private int currentProgress;
public MyViewModel()
{
this.instigateWorkCommand =
new DelegateCommand(o => this.worker.RunWorkerAsync(),
o => !this.worker.IsBusy);
this.worker = new BackgroundWorker();
this.worker.DoWork += this.DoWork;
this.worker.ProgressChanged += this.ProgressChanged;
}
// your UI binds to this command in order to kick off the work
public ICommand InstigateWorkCommand
{
get { return this.instigateWorkCommand; }
}
public int CurrentProgress
{
get { return this.currentProgress; }
private set
{
if (this.currentProgress != value)
{
this.currentProgress = value;
this.OnPropertyChanged(() => this.CurrentProgress);
}
}
}
private void DoWork(object sender, DoWorkEventArgs e)
{
// do time-consuming work here, calling ReportProgress as and when you can
}
private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.CurrentProgress = e.ProgressPercentage;
}
}
Use a ProgressBar control and bind its Value property to a property of the ViewModel:
View
<ProgressBar Minimum="0" Maximum="0" Value="{Binding CurrentProgress}" />
ViewModel
private double _currentProgress;
public double CurrentProgress
{
get { return _currentProgress; }
private set
{
_currentProgress = value;
OnPropertyChanged("CurrentProgress");
}
}
Add two properties to your VM:
bool IsProgressBarVisible
double ProgressValue
If you start a long time operation in your VM, set the IsProgressBarVisible-property to true and set the ProgressValue periodical to the current progress value. Try to calculate a value between 0 and 100. This has the advantage that you don't have to provide a minimum and maximum value.
After the asynchronous operation has completed, set the IsProgressBarVisible to false.
In XAML, bind to these two properties. Use a value converter to convert the boolean visibility to a Visibility.
<ProgressBar Value="{Binding ProgressValue}" Visibility="{Binding IsProgressBarVisible,Converter={StaticResource BooleanToVisibility_ValueConverter}}"/>
I am writing an audio app on Windows Phone 8. I've created a MediaElement and a seek-bar(slider):
<MediaElement x:Name="player" CurrentStateChanged="GetTrackDuration" />
<Slider x:Name="playerSeekBar" Value="{Binding ElementName=player, Path=Position,
Mode=TwoWay, Converter={StaticResource PositionConverter}}" SmallChange="1" LargeChange="1"/>
And this is my converter code:
public class PositionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double position = 0;
TimeSpan timespan = TimeSpan.Parse(value.ToString());
position = timespan.TotalSeconds;
return position;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return TimeSpan.FromSeconds((double)value);
}
}
And here is the CurrentStateChanged event code:
private void GetTrackDuration(object sender, RoutedEventArgs e)
{
var player = (MediaElement)sender;
if (player.CurrentState == System.Windows.Media.MediaElementState.Playing)
playerSeekBar.Maximum = player.NaturalDuration.TimeSpan.TotalSeconds;
}
It all seems to work OK, however there is one problem with the binding to slider - it doesn't update until I click somewhere inside the app - I mean i may click on a button that isn't connected with slider or media element or on a empty space. After I click the slider is being updated and everything works nice. BTW, the music plays normally - even at the beginning when the slider is not being updated. I tried to look on the Internet, however I am not sure what to ask, that's why I am asking You for help. If someone just knows where I could search for the solution, I would be very grateful!:)
Thank You for Your help in advance!
It looks like a problem when Slider gets Focus, I've tried to find a solution with redirecting Focus, but so far - I haven't found it. Instead I've a diffrent proposal and few remarks to your code:
Get track duration when Media is Opened not when PlayState changes:
private void player_MediaOpened(object sender, RoutedEventArgs e)
{
playerSeekBar.Maximum = (sender as MediaElement).NaturalDuration.TimeSpan.TotalSeconds;
}
Your Slider will probably be updated every little change of MediaElement's position. I think it isn't needed - it can be updated for example every second. So my proposal is - bind your Slider to a property, and notify PropertyChanged every second (use DispatcherTimer):
// In this case we need INotifyPropertyChanged -
public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
{
// implementing interface
public event PropertyChangedEventHandler PropertyChanged;
public void RaiseProperty(string property = null)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(property));
}
// Property for Binding
public double SlideValue
{
get { return player.Position.TotalSeconds; }
set { player.Position = TimeSpan.FromSeconds(value); }
}
DispatcherTimer timer = new DispatcherTimer(); // timer
// Get the duration when Media File is opened
private void player_MediaOpened(object sender, RoutedEventArgs e)
{
playerSeekBar.Maximum = (sender as MediaElement).NaturalDuration.TimeSpan.TotalSeconds;
}
public MainPage()
{
InitializeComponent();
this.DataContext = this; // Set the DataContext
Play.Click += Play_Click; // My play method
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += (s, e) => { RaiseProperty("SlideValue"); };
}
private void Play_Click(object sender, RoutedEventArgs e)
{
player.AutoPlay = true;
player.Source = new Uri("music.mp3", UriKind.RelativeOrAbsolute);
timer.Start(); // DON'T forget to start the timer.
}
In this case you no longer need Converters, and your XAML code can look like this:
<MediaElement x:Name="player" MediaOpened="player_MediaOpened"/>
<Slider x:Name="playerSeekBar" Value="{Binding SlideValue, Mode=TwoWay}" SmallChange="1" LargeChange="1"/>
Above code probably still needs some improvements, but works quite fine.
EDIT - method without DataBinding and INotifyPropertyChanged
You can also accomplish your task simpler way without Binding, just using Timer and LostMouseCapture:
public partial class MainPage : PhoneApplicationPage
{
private double totalSeconds = 1;
DispatcherTimer timer = new DispatcherTimer();
private void player_MediaOpened(object sender, RoutedEventArgs e)
{
totalSeconds = (sender as MediaElement).NaturalDuration.TimeSpan.TotalSeconds;
}
public MainPage()
{
InitializeComponent();
Play.Click += Play_Click;
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += (s, e) => { playerSeekBar.Value += (double)(1 / totalSeconds); };
playerSeekBar.LostMouseCapture += (s, e) =>
{ player.Position = TimeSpan.FromSeconds(playerSeekBar.Value * totalSeconds); };
}
private void Play_Click(object sender, RoutedEventArgs e)
{
player.AutoPlay = true;
player.Source = new Uri("music.mp3", UriKind.RelativeOrAbsolute);
timer.Start(); // DON'T forget to start the timer.
}
}
In XAML:
<MediaElement x:Name="player" MediaOpened="player_MediaOpened"/>
<Slider x:Name="playerSeekBar" Value="0" SmallChange="0.01" Maximum="1.0"/>
Hope this helps.
I am having issues updating a separately opened window's progress bar from a background worker inside another class.
The program execution goes like this:
MainWindow loads
Click button to do some work and open a popup
progress bar (newly opened window)
Background worker does work
and reports progress to popup progress bar
Popup progress bar
hopefully updates.
The progress bar Value is bound to a property, which in the step-through debugger, looks to be getting updated okay by the background worker. These changes just are not reflected on the popup progress bar view. However, the binding is not broken because if I manually try and set the property value for the progress bar it works fine.
Furthermore, when I put the progress bar inside the initially started MainWindow view it updates fine. Any suggestions??
Here is the some code:
MainWindowViewModel
public class MainWindowViewModel: BaseViewModel
{
private void PerformSomeAction()
{
var popUpProgressBar = new PopUpProgressBarViewModel();
popUpProgressBar.Show(popUpProgressBar);
var worker = new BackgroundWorker { WorkerReportsProgress = true };
worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
{
if (args.ProgressPercentage != popUpProgressBar.Progresser)
{
Progresser = args.ProgressPercentage;
popUpProgressBar.Progresser = args.ProgressPercentage;
}
};
worker.DoWork += delegate
{
for (int i = 0; i < 101; i++)
{
worker.ReportProgress(i);
System.Threading.Thread.Sleep(10);
}
MessageBox.Show("Done");
};
worker.RunWorkerAsync();
}
private int _progresser;
public int Progresser
{
get { return _progresser; }
set
{
if (_progresser == value) return;
_progresser = value;
OnPropertyChanged("Progresser");
}
}
private RelayCommand _startProcessing; //set private member
public ICommand StartProcessing //public field used by xaml binding
{
get
{
return _startProcessing = MakeCommandSafely(_startProcessing, () => PerformSomeAction());
}
}
}
PopUpProgressBarViewModel
public class PopUpProgressBarViewModel : BaseViewModel
{
private PopUpProgressBar _popUpProgressBar;
public void Show(PopUpProgressBarViewModel context)
{
_popUpProgressBar = new PopUpProgressBar {DataContext = context};
_popUpProgressBar.Show();
}
private int _progresser;
public int Progresser
{
get { return _progresser; }
set
{
if (_progresser == value) return;
_progresser = value;
OnPropertyChanged("Progresser");
}
}
}
For full solution file (so you can see whats happening), see here
As #Doug said, since you are already setting the DataContext:
_popUpProgressBar = new PopUpProgressBar {DataContext = context};
You can change the PopUpProgressBar to
<Window x:Class="OpeningWindow_With_ProgressBar.View.PopUpProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModel="clr-namespace:OpeningWindow_With_ProgressBar.ViewModel" Title="PopUpProgressBar" Height="150" Width="300">
<Grid>
<StackPanel>
<Label FontWeight="Bold">Loading Something</Label>
<ProgressBar Minimum="0" Maximum="100" Margin="0,10,0,0" Height="25px" Width="250px" Value="{Binding Path=Progresser, Mode=OneWay}"></ProgressBar>
<TextBlock Margin="10,10,0,0" Text="Details of loading..."></TextBlock>
</StackPanel>
</Grid>
You are creating two PopUpProgressBarViewModels. You've got one that's being created as a resource inside PopUpProgressBar.xaml, and the other one is being created in MainWindowViewModel (line 18).
Your XAML is bound to the one created inside PopUpProgressBar.xaml, while the one that you're updating is the one created in MainWindowViewModel.
If you can pare it down so only one is created, that should solve your problem.