[英]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.