繁体   English   中英

WPF MVVM:按列表视图中显示的成员筛选

[英]WPF MVVM: Filter by member displayed in the listview

我有一个listview内的gridview。 模型中有一列“部门”(Department)绑定到属性“部门”(Department),并且还关联了对流器。

Converter获取来自属性的值,并以另一种形式(带有另一个字符串)显示它。

例如,如果此属性“部门”的值在列中显示为“ 100AB”,则显示为“财务”,如果值达到“ 200CB”,则在列中显示“管理”,依此类推...

我的问题是使用过滤器过滤listview时。 在内部使用“ 100AB”,“ 200CB”而不是“ Financial”和“ Administration”显示的值进行过滤,那么如何解决呢?

查看(xaml)

<ListView Grid.Row="1" Grid.Column="0"
          Name="MyListView" 
          ItemsSource="{Binding Path=View}" 

<GridViewColumn Header="Department" Width="190"
                DisplayMemberBinding="{Binding Department, Converter={StaticResource DeptTypeConverter}}">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
             <TextBlock TextAlignment="Right"/>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

转换器

public class DeptTypeConverter: IValueConverter
{
    #region Constants

    private const string DeptFinancialType = "100AB";
    private const string DeptAdminType = "200CB";

    private const string DeptFinancialView = "Finanacial";
    private const string DeptAdminView = "Administration";

    #endregion

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Do the conversion from drink type to present it in the view
        string s = (string)value;
        if (s == DeptFinancialType )
            return DeptFinancialView;
        else if (s == DeptAdminType)
            return DeptAdminView;
        else
            throw new Exception(string.Format("Cannot convert, unknown value {0}", value));
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Do the conversion from presentation to data type
        string s = (string)value;
        if (s.Equals(DeptFinancialView, StringComparison.InvariantCultureIgnoreCase))
            return DeptFinancialType;
        else if (s.Equals(DeptAdminView, StringComparison.InvariantCultureIgnoreCase))
            return DeptAdminType;
        else
            throw new Exception(string.Format("Cannot convert, unknown value {0}", value));
    }
}

在视图模型中过滤

private CollectionView view;

public CollectionView View
{
    get
    {
        return this.view;
    }

    private set
    {
        if (this.view == value)
        {
            return;
        }

        this.view = value;
        OnPropertyChanged("View");
    }
}

// This code in constructor
this.View = (CollectionView)CollectionViewSource.GetDefaultView(this.MyListView);
this.View.Filter = UserFilter;
//

private bool MyFilter(object item)
{
    if (String.IsNullOrEmpty(this.TextToFilter))
    {
        return true;
    }
    else
    {
        DataModel m = (item as DataModel);
        bool result = (m.Department.IndexOf(this.TextToFilter, StringComparison.OrdinalIgnoreCase) >= 0);

        return result;
    }
}

我在过滤器中有其他字段,但为简单起见,我没有在MyFilter方法中指定其他字段。 该字段不使用转换器,在这种情况下没有必要,仅在我提供的情况下才需要。

DataModel是数据模型,包含视图绑定到的“部门”属性。

this.TextToFilter是视图中要作为筛选依据的文本框。

尝试#1

我没有使用DeptTypeConverter中的ConvertBack,而是使用了Convert(无需在Convert方法中进行任何修改)。 以下工作正常。

private bool MyFilter(object item)
{
    if (String.IsNullOrEmpty(this.TextToFilter))
    {
        return true;
    }
    else
    {
        DataModel m = (item as DataModel);

        bool result = (new Converters.DeptTypeConverter().Convert(m.Department, null, null, null).ToString().IndexOf(this.TextToFilter, StringComparison.OrdinalIgnoreCase) >= 0);

        return result;
    }
}

m。部门包含内部存储的值(不是显示的值)。

我认为最好使用Convert而不是ConvertBack,因为用户在搜索时键入显示的文本(内部没有存储值)。 使用ConvertBack需要更多的逻辑来实现,并且不如简单地使用Convert那样容易。

如果有人有其他更好的主意,请分享。 任何想法或改进总是欢迎的。 我尽可能不破坏MVVM模式架构。

我确实认为做到这一点的最佳方法是根本不使用IValueConverter。 我将更改您的DataModel类以添加新的DepartmentDisplay属性。 将DepartmentDisplay属性用于GridViewColumn绑定和进行过滤,将Department用于显示网格后对数据进行的任何处理。 这将是最简单,最MVMV的解决方案,它将完全删除IValueConverter。

DataModel中....

public string Department { get; set; }

public string DepartmentDisplay
{
    get
    {
        if (Department == "100AB")
            return "Financial";
        if (Department == "200CB")
            return "Administration";

        return "";
    }
}

视图...

<GridViewColumn Header="Department" Width="190"
            DisplayMemberBinding="{Binding DepartmentDisplay}">

视图模型...

private bool MyFilter(object item)
{
    if (String.IsNullOrEmpty(this.TextToFilter))
    {
        return true;
    }
    else
    {
        DataModel m = (item as DataModel);
        bool result = (m.DepartmentDisplay.IndexOf(this.TextToFilter, StringComparison.OrdinalIgnoreCase) >= 0);

        return result;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM