Reputation: 621
Hej im trying to fix this problem for days now.
I've got a ListBox
with a ProgressBar
, binded to a ObservableCollection
. Now im downloading stuff and trying to update the ProgressBar
with:
public delegate void BytesDownloadedEventHandler(ByteArgs e, Item Obj);
public static event BytesDownloadedEventHandler bytesDownloaded;
Heres the Event
where im getting the right Obj
from the ObservableCollection
private void MainWindow_bytesDownloaded(ByteArgs e, Item Obj) {
if (Obj != null) {
for (int i = 0; i < _downloadList.Count; i++) {
if (_downloadList[i].Name == Obj.Name) {
if (_downloadList[i].Value + e.downloaded <= _downloadList[i].Maximum) {
App.Current.Dispatcher.Invoke(delegate {
_downloadList[i].Minimum = 0;
_downloadList[i].Maximum = e.total;
_downloadList[i].Value += e.downloaded;
lstDowload.ItemsSource = _downloadList;
});
}
break;
}
}
}
}
and heres the ListBox
code with the ProgressBar
<ListBox Name="lstDowload" Height="350" Width="707" Visibility="Collapsed" Canvas.Left="-9">
<ListBox.ItemTemplate>
<DataTemplate>
<Canvas Height="67" Width="682">
<Canvas.ToolTip>
<ToolTip Name="albumToolTip" Width="Auto" Height="Auto">
<Canvas Width="120" Height="150">
<Image Source="{Binding ToolTipImage}" Height="152" Width="125" Stretch="Fill"/>
</Canvas>
</ToolTip>
</Canvas.ToolTip>
<ProgressBar Width="288" Canvas.Left="53" Canvas.Top="53" Height="10" Value="{Binding Value}" Maximum="{Binding Maximum}" Minimum="{Binding Minimum}"/>
<Label Foreground="#FFC3BDBD" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="11" Content="{Binding Name}" Canvas.Left="48" Canvas.Top="15"/>
<Label Foreground="#FF8D8D8D" FontFamily="{DynamicResource HeaderFontFamily}" FontSize="12" Content="{Binding Status}" Canvas.Left="48" Canvas.Top="30"/>
<Image Source="{Binding DownloadIcon}" Height="39" Width="49" Canvas.Left="-1" Canvas.Top="6"/>
</Canvas>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My Item Properties
public string Name { get; set; }
public Uri DownloadIcon { get; set; }
public int Value {get; set;}
public double Maximum { get; set; }
public int Minimum { get; set; }
Now my problem is that the ProgressBar
just stays at 100% and nothing happens.
Maybe somebody could give me a hint or something. This is to complicated for me :) im trying everything but still the same :(
Upvotes: 3
Views: 623
Reputation: 9975
The item type used in the ObservableCollection must implement INotifyPropertyChanged for the UI to take note of the changes.
Also since you're using an observable collection you only need to assign the ItemsSource once, actually you can bind it to a property on whatever object you assign to be your windows Datacontext
Something like:
public class Item : INotifyPropertyChanged
{
private Double value;
public Double Value
{
get { return this.value; }
set { this.value = value; Changed("Value"); }
}
private Double minimum;
public Double Minimum
{
get { return minimum; }
set { minimum = value; Changed("Minimum"); }
}
private Double maximum;
public Double Maximum
{
get { return maximum; }
set { maximum = value; Changed("Maximum"); }
}
private string name;
public string Name
{
get { return name; }
set { name = value; Changed("Name"); }
}
private string status;
public string Status
{
get { return status; }
set { status = value; Changed("Status"); }
}
private void Changed(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
Here's the xaml used for testing:
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<ProgressBar Width="288" Height="10" Value="{Binding Value}" Maximum="{Binding Maximum}" Minimum="{Binding Minimum}"/>
<Label Foreground="#FFC3BDBD" FontSize="11" Content="{Binding Name}"/>
<Label Foreground="#FF8D8D8D" FontSize="12" Content="{Binding Status}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And the code behind...
public partial class MainWindow : Window
{
Timer timer2 = new Timer(3000);
Timer timer = new Timer(100);
Dispatcher gui = Dispatcher.CurrentDispatcher;
public MainWindow()
{
InitializeComponent();
Items = new ObservableCollection<Item>();
this.DataContext = this;
timer.Elapsed += (s, e) =>
{
gui.Invoke(() => new Action(() =>
{
foreach (Item item in Items)
{
if (item.Value < item.Maximum)
{
item.Value++;
}
}
}).Invoke());
};
timer.Enabled = true;
Random rand = new Random();
timer2.Elapsed += (s, e) =>
{
gui.Invoke(() =>
Items.Add(new Item()
{
Minimum = rand.Next(1, 30),
Maximum = rand.Next(35, 100),
}));
};
timer2.Enabled = true;
}
public ObservableCollection<Item> Items
{
get;
private set;
}
}
Upvotes: 3