Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将转换器应用于ObservableCollection的每个项目?_C#_Wpf_Mvvm - Fatal编程技术网

C# 如何将转换器应用于ObservableCollection的每个项目?

C# 如何将转换器应用于ObservableCollection的每个项目?,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在使用C#和.NET4.5创建一个MVVM桌面应用程序。我有一组视图模型条目,它们已经包含在ObservableCollection中 我需要使用第三方控件来显示数据。此控件要求将条目转换为它们自己的条目类。它们提供了如何使用XAML和IValueConverter实现这一点的示例。它归结为…Items=“{Binding Path=The.Source,Converter={StaticResource CustomDataConverter}}…”和一个大致如下实现的转换器: publi

我正在使用C#和.NET4.5创建一个MVVM桌面应用程序。我有一组视图模型条目,它们已经包含在
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属性的最末端)我无法让它工作-即使在从他们的网站插入未更改的代码后,控件仍然是空的。。。。