WPF DataGrid:将Collection属性绑定到Column

时间:2014-08-12 14:23:56

标签: wpf collections binding datagrid

我有一个名为Person的类:

public class Person
{
  private string _Name;
  private ObservableCollection<Smartphone> _Smartphones;

  // Properties
}

public class Smartphone
{
    private string _Manufacturer;
    private bool _IsWorking;

    // Properties
}

在我的视图中,我有一个DataGrid。 我的问题是:

有没有办法让我的DataGrid看起来像这样:

enter image description here

所有人的收藏中都有相同的智能手机,但是“IsWorking”具有不同的价值......

修改 我在DataGrid中尝试使用DataGrid,如:

<DataGrid ItemsSource="{Binding PersonCollection}"
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}" Header="Name" />
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <DataGrid ItemsSource="{Binding Smartphones}">
                            </DataGrid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>

但这不是我想要的“解决方案”......

编辑2 :如果可能有一个Checkbox而不是“true / false”,那会很不错:) ...

1 个答案:

答案 0 :(得分:9)

试试这个

  

SmartPhone.cs Person.cs

public class Person 
{
    public string Name { get; set; }

    public ObservableCollection<SmartPhone> SmartPhones { get; set; }
}

public class SmartPhone
{
    public string Manufacturer { get; set; }

    public bool IsWorking { get; set; }
}
  

修改如果您想动态尝试此

     

自定义DataGrid和转换器

    public class MyDataGrid:DataGrid
{
    public ObservableCollection<string> ColumnHeaders
    {
        get { return GetValue(ColumnHeadersProperty) as ObservableCollection<string>; }
        set { SetValue(ColumnHeadersProperty, value); }
    }

    public static readOnly DependencyProperty ColumnHeadersProperty = DependencyProperty.Register("ColumnHeaders", typeof(ObservableCollection<string>), typeof(MyDataGrid), new PropertyMetadata(new PropertyChangedCallback(OnColumnsChanged)));

    static void OnColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var dataGrid=d as MyDataGrid;
        dataGrid.Columns.Clear();
        //Add Person Column
        dataGrid.Columns.Add(new DataGridTextColumn() { Header = "Name", Binding = new Binding("Name") });
        //Add Manufactures Columns
        foreach (var value in dataGrid.ColumnHeaders)
        {
            var column=new DataGridCheckBoxColumn(){Header=value,Binding=new Binding("SmartPhones"){ConverterParameter=value,Converter=new ManufacturerConverter()}};
            dataGrid.Columns.Add(column);
        }
    }
}

public class ManufacturerConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var smartPhones = value as IEnumerable<SmartPhone>;
        if (smartPhones != null && parameter!=null)
        {
            var phone=smartPhones.FirstOrDefault(s => s.Manufacturer == parameter.ToString());
            if (phone != null)
                return phone.IsWorking;
            return false;
        }
        return false;
    }

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

XAML

    <StackPanel>
    <local:MyDataGrid AutoGenerateColumns="False"
                      ColumnHeaders="{Binding ColumnHeaders}"
                      ItemsSource="{Binding PersonCollection}"
                      CanUserAddRows="False" IsReadOnly="True">

    </local:MyDataGrid>
</StackPanel>
  

xaml.cs

    public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }
}
  

视图模型

public class ViewModel
{
    public ViewModel()
    {
        ColumnHeaders = new ObservableCollection<string>();
        PersonCollection = new ObservableCollection<Person>()
        {
            new Person(){Name="Foo",
                SmartPhones=new ObservableCollection<SmartPhone>()
                {new SmartPhone(){Manufacturer="Manufacturer1",IsWorking=true}
                    ,new SmartPhone(){Manufacturer="Manufacturer2",IsWorking=false}}}
        , new Person(){Name="Bar",
                SmartPhones=new ObservableCollection<SmartPhone>()
                {new SmartPhone(){Manufacturer="Manufacturer1",IsWorking=true}
                    ,new SmartPhone(){Manufacturer="Manufacturer2",IsWorking=false}
                    ,new SmartPhone(){Manufacturer="Manufacturer3",IsWorking=true}}}

        , new Person(){Name="FooBar",
                SmartPhones=new ObservableCollection<SmartPhone>()
                {new SmartPhone(){Manufacturer="Manufacturer1",IsWorking=true}
                    ,new SmartPhone(){Manufacturer="Manufacturer2",IsWorking=false}
                    ,new SmartPhone(){Manufacturer="Manufacturer3",IsWorking=true}
                    ,new SmartPhone(){Manufacturer="Manufacturer4",IsWorking=false}
                    ,new SmartPhone(){Manufacturer="Manufacturer5",IsWorking=true}
                }}


        };
        foreach (var item in PersonCollection.SelectMany(s=>s.SmartPhones).Select(s=>s.Manufacturer).Distinct())
        {
            ColumnHeaders.Add(item);
        }
    }

    public ObservableCollection<Person> PersonCollection { get; set; }

    public ObservableCollection<string> ColumnHeaders { get; set; }
}
  

输出

Output

  

我希望这会有所帮助。