【问题标题】:WPF Binding GridView to Element in collectionWPF 将 GridView 绑定到集合中的元素
【发布时间】:2014-01-20 15:07:04
【问题描述】:

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

我已经设置好了:

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;}
}

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

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

规则 = 行 条件 = 列

目前,当用户从一个 RuleGroup 移动到下一个 RuleGroup 时,我有一个基于规则/标准生成 DataTable 的函数,但我认为我有一个更好的解决方案

任何想法或帮助将不胜感激

谢谢

【问题讨论】:

    标签: c# wpf gridview mvvm binding


    【解决方案1】:

    没错,我明白了。

    需要稍微更改我的类以获得正确的组/层次结构。然后我就能够使用集合中的项目索引绑定列。

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

    这是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; }
    }
    

    规则字段

    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;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-27
      • 1970-01-01
      • 1970-01-01
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多