ObservableCollection不更新我的UI

时间:2015-06-14 13:40:19

标签: wpf listview

这是我的模特:

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));
    }
}

我的模特集:

public ObservableCollection<WireshrkFile> files{ get; set; }

我的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>

我可以看到我的收藏品属性发生变化,但mu UI没有。

1 个答案:

答案 0 :(得分:1)

注意:请注意:ItemsSource="{Binding WiresharkFile}"

将其更改为ItemsSource="{Binding files}"

我准备了一个小样本:

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>

简单视图,您有一个ProgressBar,其Value绑定到模型中的属性。

这是模特:

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 { };
}

我认为这里没有什么可解释的,你有同样的方法。

这是我的测试代码:

 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;
        }
    }
}

因此,当我点击按钮时,所有ProgressBars都将完成。

我发现你没有为这些属性实施INPC:

  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

使用实际表单时,如果发生更改,则不会通知View。