【问题标题】:After filtering data in view model it's not showing/refreshing view在视图模型中过滤数据后,它不显示/刷新视图
【发布时间】:2016-05-20 09:22:41
【问题描述】:

我有两种类型的站点列表,我通过下面的代码在视图模型中过滤

  public void FilterSite()
    {
        if (SelectedItem.Contains("EC350"))

            listofsites = new ObservableCollection<SiteDetails>(listofsites.Where(p => Convert.ToString(p.DeviceType) == "MiCell_Ec350"));
        else if (SelectedItem.Contains("MiCell"))
            listofsites = new ObservableCollection<SiteDetails>(listofsites.Where(p => Convert.ToString(p.DeviceType) == "MiCell"));
        else if (SelectedItem.Contains("Mini-Max"))
            listofsites = new ObservableCollection<SiteDetails>(listofsites.Where(p => Convert.ToString(p.DeviceType) == "Mini-Max"));


    }

现在为了在 listofsites 中获取自动更新,我正在属性设置器中实现 InotifyPropertyChangedOnPropertyChanged p>

public class SiteMainUC_VM : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }


    private ObservableCollection<SiteDetails> listofsites = null;
    public ObservableCollection<SiteDetails> Listofsites
    {
        get
        {
            return listofsites;
        }
        set
        {
            listofsites = value;
            OnPropertyChanged("Listofsites");
        }
    }

在组合框选择值后,通过调试我看到过滤值但视图未显示。现在对于绑定,我已经尝试了单向/双向,但没有工作。下面是xaml代码-

<ComboBox Name="cmbSiteSearch" SelectedValue="{Binding SelectedItem, Mode=TwoWay}" Text="{Binding SearchFilter,UpdateSourceTrigger=PropertyChanged}"  Height="18" Width="18" IsReadOnly="True" FontFamily="Arial"   >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="SelectionChanged">
                        <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
                <ComboBox.Background>
                    <ImageBrush ImageSource="/MasterLink;component/Resources/i_filter.png"    />
                </ComboBox.Background>
                <ComboBoxItem Content="All" Height="34" Width="190" FontFamily="Arial" FontSize="12" />
                <ComboBoxItem Content="EC350" Height="34" Width="190" FontFamily="Arial" FontSize="12"/>
                <ComboBoxItem Content="Mini-Max" Height="34" Width="190" FontFamily="Arial" FontSize="12"/>
            </ComboBox>

现在我有站点列表列表框代码

<ListBox    ItemsSource="{Binding Listofsites}"  SelectedItem="{Binding Path=Selectedsites, Mode=TwoWay,NotifyOnSourceUpdated=True}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Height="600" 
          SelectionChanged="ListBox_SelectionChanged" >

【问题讨论】:

  • 使用 Observable 集合,您不必实现 OnPropertyChanged,而是应该使用 Collection.Clear()。并将所有新项目添加到集合中,例如 Collection.Add(filteredItem)
  • 试过了。但没有得到。
  • 您是否也对子视图模型(即 SiteDetails)做了同样的通知
  • 不,没有,因为客户端提供的所有数据都来自此应用程序的 api [dll]。既然你说我就试试。感谢您的提示。

标签: c# wpf c#-4.0 mvvm combobox


【解决方案1】:
 public void FilterSite()
    {
     listofsites = new ObservableCollection<SiteDetails>(parameters);

if (SelectedItem.Contains("EC350"))

            Listofsites = new ObservableCollection<SiteDetails>(listofsites.Where(p => Convert.ToString(p.DeviceType) == "MiCell_Ec350"));
        else if (SelectedItem.Contains("MiCell"))
            Listofsites = new ObservableCollection<SiteDetails>(listofsites.Where(p => Convert.ToString(p.DeviceType) == "MiCell"));
        else if (SelectedItem.Contains("Mini-Max"))
            Listofsites = new ObservableCollection<SiteDetails>(listofsites.Where(p => Convert.ToString(p.DeviceType) == "Mini-Max"));


    }

1)在过滤器方法内部添加私有变量以将其与可观察集合绑定,否则一旦您过滤了您的值,它的值将为空,并且通过第二次点击您将不会通过过滤获得任何值更改。

2) 有时在此处分配私有变量 listofsites 不会给您想要的结果,并且通过视图与视图模型进行通信会出现问题。虽然这是一种糟糕的编码风格,但使用直接属性名称而不是变量,I,e; 网站列表

3)我也遇到过几次类似的视图刷新问题。要获得更好的风格,您应该选择 MessageBus 架构风格。可以实现发布/订阅样式,用于与 vm to vm 或 vm to view 通信。

以下链接https://msdn.microsoft.com/en-us/library/ff647328.aspx

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您忘记将 ComboBox 的 ItemsSource 绑定到基础集合。您的 XAML 应如下所示:

    <ComboBox x:Name="cmbSiteSearch" Height="18" Width="18" 
              IsReadOnly="True" FontFamily="Arial"
              Text="{Binding SearchFilter, UpdateSourceTrigger=PropertyChanged}"
              ItemsSource="{Binding Listofsites}"/>
    

    【讨论】:

    • 已经列表框[所有站点列表]包含ItemsSource="{Binding Listofsites}",这就是为什么如果我为组合框输入相同的东西,它会给出错误。
    • 如果没有完整的上下文,仍然很难理解问题。你确定你正确设置了 DataContext 吗?在 FilterSite() 方法中,您将值分配给 listofsites 字段而不是 Listofsites 属性,这不会导致 OnPropertyChanged 调用。
    猜你喜欢
    • 2021-06-01
    • 2023-03-25
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多