Reputation: 567
This is my Model:
public class WiresharkFile : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
virtual public void NotifyPropertyChange(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
private string _file; // file path
private string _packets; // how many packet in file
private string _sentPackets; // how many packet sent
private string _progress; // percentage (_sentPackets/_packets) * 100
public int Progress
{
get { return _progress; }
set
{
_progress = value;
NotifyPropertyChange("Progress");
}
}
public void Transmit(WireshrkFile)
{
// here i am send the packets
}
public event PropertyChangedEventHandler PropertyChanged;
virtual public void NotifyPropertyChange(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
My model collection:
public ObservableCollection<WireshrkFile> files{ get; set; }
My ListView
:
<ListView Name="lvFiles" Margin="16,455,0,65" Background="Transparent" BorderThickness="0,1,0,1"
ItemsSource="{Binding pcapFiles}" MouseDoubleClick="lvPcapFiles_MouseDoubleClick"
MouseDown="lvPcapFiles_MouseDown" MouseLeftButtonDown="lvPcapFiles_MouseLeftButtonDown" >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Padding" Value="4,1"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Foreground" Value="Black"></Setter>
<Setter Property="Background" Value="#FFD8D5D5"/>
<Setter Property="BorderBrush" Value="White"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False"/>
<Condition Property="IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#FF15669E"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="True"/>
<Condition Property="IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#FF15669E"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<DataTemplate x:Key="MyDataTemplate">
<Grid Margin="-6">
<ProgressBar Name="progressBarColumn" Maximum="100" Value="{Binding Progress}"
Width="{Binding Path=Width, ElementName=ProgressCell}"
Height="20" Margin="0" Background="Gray" Style="{StaticResource CustomProgressBar}" />
<TextBlock Text="{Binding Path=Value, ElementName=progressBarColumn, StringFormat={}{0}%}" VerticalAlignment="Center"
HorizontalAlignment="Center" FontSize="11" Foreground="White" />
</Grid>
</DataTemplate>
<ControlTemplate x:Key="ProgressBarTemplate">
<Label HorizontalAlignment="Center" VerticalAlignment="Center" />
</ControlTemplate>
</ListView.Resources>
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource ListViewHeaderStyle}">
<!-- file name column -->
<GridViewColumn Width="420" Header="File name" DisplayMemberBinding="{Binding FileName}" />
<!-- duration column -->
<GridViewColumn Width="60" Header="Duration" DisplayMemberBinding="{Binding Duration}" />
<!-- packets column -->
<GridViewColumn Width="80" Header="Packets" DisplayMemberBinding="{Binding Packets}" />
<!-- packet sent -->
<GridViewColumn Width="80" Header="Packet sent" DisplayMemberBinding="{Binding PacketsSent}" />
<!-- progress column -->
<GridViewColumn x:Name="ProgressCell" Width="50" Header="Progress" CellTemplate="{StaticResource MyDataTemplate}" />
</GridView>
</ListView.View>
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="Open Capture" FontSize="12" FontFamily="Microsoft Sans Serif"
Click="MenuItem_Click" VerticalAlignment="Center" Height="20">
<MenuItem.Icon>
<Image Height="18" Width="18" VerticalAlignment="Center"
Source="C:\Users\rsteinbe\Dropbox\PacketPlayer\PacketPlayer\resources\wireshark.ico" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</ListView.ContextMenu>
</ListView>
I can see that my collection properties changing but mu UI
not.
Upvotes: 2
Views: 284
Reputation: 2620
Note: Pay attention here: ItemsSource="{Binding WiresharkFile}"
Change this to ItemsSource="{Binding files}"
I've prepared a small sample:
Window x:Class="ProgressBarChangedStack.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<ListView ItemsSource="{Binding files}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="Progress: "/>
<ProgressBar Value="{Binding Progress}" Margin="5" MinWidth="100"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Content="Click to complete progress" Width="150" Margin="10" Click="btnProgressComplete_Click"/>
</StackPanel>
</Grid>
Simple View, you have a ProgressBar
there with its Value
bound to a property from the Model.
This is the Model:
public class Model : INotifyPropertyChanged
{
private int _Progress;
public int Progress
{
get { return _Progress; }
set
{
_Progress = value;
PropertyChanged(this, new PropertyChangedEventArgs("Progress"));
}
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
I think there is nothing to explain here, you have the same approach.
And here is my testing code:
public partial class MainWindow : Window
{
public ObservableCollection<Model> files { get; set; }
public MainWindow()
{
InitializeComponent();
files = new ObservableCollection<Model>();
files.Add(new Model() { Progress = 20 });
files.Add(new Model() { Progress = 30 });
files.Add(new Model() { Progress = 40 });
this.DataContext = this;
}
private void btnProgressComplete_Click(object sender, RoutedEventArgs e)
{
foreach (var file in files)
{
file.Progress = 100;
}
}
}
So, when i click the Button, all the ProgressBars will be complete.
I see you don't have INPC implemented for these properties:
private string _file; // file path
private string _packets; // how many packet in file
private string _sentPackets; // how many packet sent
private string _progress; // percentage (_sentPackets/_packets) * 100
With their actual form, the View will not be inform when changes occur.
Upvotes: 1