我在listview中有gridview。有一栏,"部门"这是绑定到一个财产"部门"在模型中它也与一个对流器相关联。
Converter获取来自属性的值,并以另一种形式显示它(使用另一个字符串)。
例如,如果此属性"部门"的值为" 100AB"在列中显示为"财务",如果值到达" 200CB"在列中显示"管理"等等...
我的问题是使用过滤器过滤listview时。在内部,它按" 100AB"," 200CB"而不是显示的值"财务"和"管理",那么如何解决这个问题?
查看(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是数据模型,包含&#34; Department&#34;视图被绑定的属性。
this.TextToFilter是视图中的文本框,用于过滤。
ATTEMPT#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.Department包含内部存储的值(不是显示的值)。
我认为最好使用Convert而不是ConvertBack作为用户在搜索时键入显示的文本(没有内部存储的值)。使用ConvertBack需要更多的逻辑来实现,并不像使用简单转换那么容易。
如果有人有更好的想法,请分享。任何想法或改进总是受欢迎的。我希望尽可能不打破MVVM模式架构。
答案 0 :(得分:0)
我觉得最好的办法就是不要使用IValueConverter。我会更改您的DataModel类以添加新的DepartmentDisplay属性。对于GridViewColumn绑定和过滤使用DepartmentDisplay属性,对于在显示网格后对数据执行的操作,使用Department。这将是最简单和最MVVM的解决方案,它完全删除了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;
}
}