C# 如何将转换器应用于ObservableCollection的每个项目?
我正在使用C#和.NET4.5创建一个MVVM桌面应用程序。我有一组视图模型条目,它们已经包含在C# 如何将转换器应用于ObservableCollection的每个项目?,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在使用C#和.NET4.5创建一个MVVM桌面应用程序。我有一组视图模型条目,它们已经包含在ObservableCollection中 我需要使用第三方控件来显示数据。此控件要求将条目转换为它们自己的条目类。它们提供了如何使用XAML和IValueConverter实现这一点的示例。它归结为…Items=“{Binding Path=The.Source,Converter={StaticResource CustomDataConverter}}…”和一个大致如下实现的转换器: publi
ObservableCollection
中
我需要使用第三方控件来显示数据。此控件要求将条目转换为它们自己的条目类。它们提供了如何使用XAML和IValueConverter
实现这一点的示例。它归结为…Items=“{Binding Path=The.Source,Converter={StaticResource CustomDataConverter}}…”
和一个大致如下实现的转换器:
public class CustomDataConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
IEnumerable<CustomItem> dataContext = value as IEnumerable<CustomItem>;
ObservableCollection<OutputItem> items = new ObservableCollection<OutputItem>();
foreach (CustomItem customItem in dataContext)
{
OutputItemitem =
new OutputItem
{
// ... some value transfers ...
};
items.Add(item);
}
return items;
}
<ListBox ItemsSource="{Binding Path=The.Source}">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Converter={StaticResource CustomDataConverter}}"
ContentTemplate="{StaticResource MyOptionalDataTemplate}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
公共类CustomDataConverter:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
IEnumerable dataContext=作为IEnumerable的值;
ObservableCollection items=新的ObservableCollection();
foreach(dataContext中的CustomItem CustomItem)
{
输出项=
新门诊
{
//…一些价值转移。。。
};
项目。添加(项目);
}
退货项目;
}
虽然这对控件的初始化有效,但它打破了“观察链”"在控件和绑定中指定的observateCollection
之间——这仅仅是因为自定义转换器创建了自己的项列表。是否有方法更改绑定指令,使转换器不会对整个源集合调用一次,而是对每个集合元素调用一次?如果没有,有什么替代方法是否存在应对这种情况的积极策略
(在上面的示例中,我省略了一些将事件处理程序注册到源对象的PropertyChanged
事件并更新目标对象的代码。单个项目属性的更新工作正常,只是列表的更新未被处理。)
编辑:所讨论的第三方控件是来自的。如果此第三方控件提供这种可能性,您可以尝试在ItemTemplate中使用转换器。对于标准WPF控件,它应该如下所示:
public class CustomDataConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
IEnumerable<CustomItem> dataContext = value as IEnumerable<CustomItem>;
ObservableCollection<OutputItem> items = new ObservableCollection<OutputItem>();
foreach (CustomItem customItem in dataContext)
{
OutputItemitem =
new OutputItem
{
// ... some value transfers ...
};
items.Add(item);
}
return items;
}
<ListBox ItemsSource="{Binding Path=The.Source}">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Converter={StaticResource CustomDataConverter}}"
ContentTemplate="{StaticResource MyOptionalDataTemplate}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
但实现这一点的最简单方法可能是绑定包含outputitem的集合…另一种方法可能是忘记在XAML代码中使用转换器,而在ViewModel中进行转换 您发布的转换器没有
ConvertBack
方法,因此我猜您的thirdy parts控件所需的ObservableCollection
列表是只读的,这意味着从XAML到C#不会发生任何修改-正如大家使用图表库所假设的那样
因此,您可以有两个属性,一个私有属性包含您将根据业务逻辑在ViewModel中更新的自定义对象,然后一个公共属性绑定到您的thirdy parts UserControl:
private ObservableCollection<OutputItem> myPrivateData
{
get;
set;
}
private ObservableCollection<CustomItem> DataToPlotOnGant
{
get;
set;
}
然后选择更新
DataToPlotOnGant
列表,方法是只修改在私有集合中更改的项-更有效-或者像转换器那样每次创建新集合。我添加了一个指向问题所用控件的链接。该控件支持ItemTemplate
属性,因此我可以实现您的建议没有语法错误。但是,我的转换器没有被调用-控件保持为空,代码永远不会执行。我还需要做什么来正确连接它吗?ContentTemplate=“{StaticResource MyOptionalDataTemplate}”应该删除该部分,因为-我猜-您没有指定自定义ContentTemplate。如果之后它仍然不起作用,请查看以下链接:。基本上,您可以使用该模板并使用转换器扩展绑定(它几乎位于ContentControl的Content属性的最末端)我无法让它工作-即使在从他们的网站插入未更改的代码后,控件仍然是空的。。。。