WPF将GridView绑定到集合中的Element

时间:2014-01-20 15:07:04

标签: c# wpf gridview mvvm binding

我正在创建一个表单,允许用户向数据添加过滤器以进行处理。

我已经设置好了:

public Class RuleGroup
{
   public ObservableCollection<Rule> Rules {get; set;}
   ...
}

public Class Rule
{
   public ObservableCollection<String> Fields {get; set;}
   public ObservableCollection<Rule> Rules {get; set;}
   ...
}

public class Criteria
{
     public int ItemId{ get; set;}
     public string Field{ get; set;}
     public OperationType Operation{ get; set;}
     public string Value {get; set;}
     public string Value2 {get; set;}
}

因此,如果要应用规则,则规则具有必须匹配的标准列表。规则中的每个条件必须为所选的每个字段指定一个值。字段数量可能因One RuleGroup而异。

我正在尝试设置一个在创建多个规则时用户友好的表单。我想在表单上有一个GridView,它与这个类布局的绑定有关。

规则=行 标准=列

目前我有一个函数,当用户从一个RuleGroup移动到另一个RuleGroup时,会根据规则/条件生成DataTable,但我认为我的解决方案更好了

非常感谢任何想法或帮助

由于

1 个答案:

答案 0 :(得分:0)

正确的想法我已经得到了它。

需要稍微改变我的类以获得正确的组/层次结构。然后,我可以使用集合中的items索引来绑定列。

这给了我想要的结果,虽然有一个小问题,我希望能够使用字符串Name而不是位置来访问索引。我目前必须确保在访问值时“Criterion”的顺序正确。

以下是Source code

的链接

规则组

public class RuleGroup
{
    public String Description { get; set; }
    public ObservableCollection<Rule> Rules { get; set; }

    public RuleGroup()
    {
        Rules = new ObservableCollection<Rule>();
    }
}

<强>规则

public class Rule
{
    public Rule()
    {
        Criteria = new ObservableCollection<Criteria>();
    }

    public String Description { get; set; }
    public ObservableCollection<Criteria> Criteria { get; set; }

    readonly ObservableCollection<RuleField> _Fields = new ObservableCollection<RuleField>();
    public IEnumerable<RuleField> Fields
    {
        get
        {
            return _Fields;
        }

    }

    public void AddField(string name, string header)
    {
        if (_Fields.FirstOrDefault(i => i.Name == name) == null)
        {
            RuleField field = new RuleField(_Fields.Count)
            {
                Name = name,
                Header = header
            };

            _Fields.Add(field);

            AddFieldToCriteria(field);

        }

    }

    void AddFieldToCriteria(RuleField field)
    {
        foreach (Criteria c in Criteria)
        {
            if (c.Values.FirstOrDefault(i => i.Field == field) == null)
                c.Values.Add(new Criterion() { Field = field, Operation = 1 });
        }
    }
}

<强>标准

public class Criteria
{
    public Criteria()
    {
        Values = new ObservableCollection<Criterion>();
    }

    public ObservableCollection<Criterion> Values { get; set; }

    public Criterion this[int index]
    {
        get
        {
            return Values.OrderBy(i=>i.Field.Position).ElementAt(index);
        }
        set
        {
            Criterion c = Values.OrderBy(i => i.Field.Position).ElementAt(index);
            c= value;
        }
    }

}

<强>标准

public class Criterion
{
    public RuleField Field { get; set; }
    public int Operation { get; set; }
    public object Value { get; set; }
    public object Value2 { get; set; }
}

<强> RuleField

public class RuleField
{
    public string Name { get; set; }
    public string Header { get; set; }

    int _Position = 0;

    public int Position
    {
        get
        {
            return _Position;
        }
    }

    public RuleField(int position)
    {
        _Position = position;
    }
}

查看模型

public delegate void UpdateColumnsEventHandler(object sender, UpdateColumnsEventArgs e);

public class UpdateColumnsEventArgs
{
    public IEnumerable<RuleField> Columns { get; set; }

    public UpdateColumnsEventArgs()
    {
        Columns = new List<RuleField>();
    }

    public UpdateColumnsEventArgs(IEnumerable<RuleField> columns)
    {
        Columns = columns;
    }
}

public class MainWindowViewModel
{
    public event UpdateColumnsEventHandler UpdateColumns;

    public ObservableCollection<RuleGroup> RuleGroups { get; set; }

    RuleGroup _SelectedRuleGroup = null;
    public RuleGroup SelectedRuleGroup
    {
        get
        {
            return _SelectedRuleGroup;
        }
        set
        {
            if (_SelectedRuleGroup == value)
                return;

            _SelectedRuleGroup = value;

        }
    }

    public Rule _SelectedRule = null;
    public Rule SelectedRule
    {
        get
        {
            return _SelectedRule;
        }
        set
        {
            if (_SelectedRule == value)
                return;

            _SelectedRule = value;

            if (UpdateColumns != null)
                UpdateColumns(this, new UpdateColumnsEventArgs(_SelectedRule.Fields));
        }
    }

    public MainWindowViewModel()
    {
        RuleGroups = new ObservableCollection<RuleGroup>();

        RuleGroup rg = new RuleGroup();
        rg.Description = "Rule Group A";

        Rule r = new Rule();
        r.Description = "Rule 1";

        Random random = new Random();
        int range = 10000;

        for (int x = 0; x < 2000; x++)
        {
            Criteria c = new Criteria();
            c.Values.Add(new Criterion()
            {
                Field = new RuleField(0)
                {
                    Name = "A",
                    Header = "A Column"
                },
                Operation = 1,
                Value = "X"
            });

            c.Values.Add(new Criterion()
            {
                Field = new RuleField(0)
                {
                    Name = "B",
                    Header = "B Column"
                },
                Operation = 1,
                Value = x % 10
            });

            r.Criteria.Add(c);
        }

        #region Fields

        r.AddField("A", "A Column");
        r.AddField("B", "B Column");
        r.AddField("C", "C Column");

        #endregion

        rg.Rules.Add(r);

        r = new Rule();
        r.Description = "Rule 2";

        for (int x = 0; x < 1750; x++)
        {
            r.Criteria.Add(new Criteria());
        }

        #region Fields

        r.AddField("A", "A Column");
        r.AddField("B", "B Column");

        #endregion

        rg.Rules.Add(r);

        RuleGroups.Add(rg);
    }
}

WPF窗口

<Window x:Class="RuleMappingTest.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:RuleMappingTest"
                Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <vm:MainWindowViewModel UpdateColumns="UpdateGridColumns"/>
    </Window.DataContext>
    <Grid Name="LayoutRoot">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <ListBox Grid.Row="0" ItemsSource="{Binding RuleGroups}" SelectedItem="{Binding SelectedRuleGroup}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Description}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <ListBox Grid.Row="1" ItemsSource="{Binding SelectedRuleGroup.Rules}" SelectedItem="{Binding SelectedRule}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Description}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <DataGrid x:Name="CriteriaGrid" Grid.Row="2" ItemsSource="{Binding SelectedRule.Criteria}" AutoGenerateColumns="False" >
        </DataGrid>
    </Grid>
</Window>

WPF代码

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

    }
    public void UpdateGridColumns(object sender, UpdateColumnsEventArgs e)
    {
        CriteriaGrid.Columns.Clear();
        foreach (RuleField rf in e.Columns)
        {
            DataGridTextColumn c = new DataGridTextColumn();
            c.Header = rf.Header;
            Binding b = new Binding(String.Format("[{0}].Value", rf.Position));
            CriteriaGrid.Columns.Add(c);
            c.Binding = b;
        }
    }
}