2

我有一个简单的 Observable 集合,它有两个公共属性,int ID 和 List Targets。代码隐藏看起来像(简化代码以删除不必要且不相关的代码):

public class MyClass
{
   public ObservableCollection<SomeClass> jobs;

   public class SomeClass
   {
      private int id;
      private List<string> targets;

      public int ID
      {
         get { return id; }
         set { id = value; }
      }

      public List<string> Targets
      {
         get { return targets; }
         set { targets = value; }
      }

      public SomeClass(int _id, List<string> _targets)
      {
         id = _id;
         targets = _targets;
      }
   }

   public MyClass()
   {
      InitializeComponent();
      jobs = new ObservableCollection<SomeClass>();
      myListView.ItemsSource = jobs; //jobs is populated from a a loader in Window_Loaded
   }
}

xaml 中的 ListView 和绑定如下所示:

  <ListView Name="MyListView" ItemsSource="{Binding Path=jobs, RelativeSource={RelativeSource AncestorType=Window},
            Mode=OneWay}" Width="480" Height="155" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,35,10,0" >
     <ListView.ContextMenu>
        <ContextMenu Name="contextMenuJobRemove">
           <ContextMenu.BitmapEffect>
              <OuterGlowBitmapEffect />
           </ContextMenu.BitmapEffect>
           <MenuItem Header="Remove" Click="contextMenuJobRemove_Click" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Parent}"/>
        </ContextMenu>
     </ListView.ContextMenu>
     <ListView.View>
        <GridView AllowsColumnReorder="True" ColumnHeaderToolTip="Broadcast call targets">
           <GridViewColumn DisplayMemberBinding="{Binding Path=ID}"   Header="ID"      Width="50" />
           <GridViewColumn DisplayMemberBinding="{Binding Path=Targets}" Header="Targets" Width="100" />
        </GridView>
     </ListView.View>
  </ListView>

因此,当 ListView 显示时,Targets 列正确地显示“(集合)”。理想情况下,我希望此列显示类似String.Join(",", Targets.ToArray()). 如何做到这一点,我是在 xaml 还是代码隐藏中做到这一点?

4

3 回答 3

4

一种方法是绑定中的转换器。

但是,这只会在属性更改(而不是集合内容)后更新。因此,最好在您的对象中公开一个显示字符串属性,并在列表更改时触发该属性的更改通知。如果集合一开始没有改变,那么这些通知显然是没有必要的。

于 2012-08-30T15:32:30.000 回答
2

使用值转换器:

[ValueConversion(typeof(IEnumerable<string>), typeof(string))]
public class MyArrayToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return String.Join (",", ( (IEnumerable<string>)value ).ToArray() );
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        throw new NotImplementedException ();
    }
}

<Window
    ...
    xmlns:my="clr-namespace:XXXXXXXXXXXXXXXXXXXXXCSharpNamespace"
    ...>
    <Window.Resources>
        <my:MyArrayToStringConverter x:Key="myconverter" />
    </Window.Resources>
    ...
    "{Binding ... Converter={StaticResource myconverter}}"
</Window>
于 2012-08-30T15:37:52.930 回答
1

您可以创建一个简单的值转换器:

public class ListConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
                          CultureInfo culture)
    {
        var enumerable = value as IEnumerable;
        if (enumerable == null)
            return string.Empty;
        return String.Join(", ", enumerable.ToArray());
    }

    public object ConvertBack(object value, Type targetType, object parameter,
                              CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
于 2012-08-30T15:36:01.057 回答