【问题标题】:WPF binding listview to Dictionary<string, Dictionary<string, bool>>WPF 将列表视图绑定到 Dictionary<string, Dictionary<string, bool>>
【发布时间】:2016-05-10 05:22:22
【问题描述】:

我有一个问题,我必须从数据库中获取List&lt;string&gt;,在其上创建Dictionary&lt;Dictionary&lt;string, bool&gt;&gt; 并用它填充listview

这是我的代码:

xaml:

    <ListView x:Name="PlanningDataGrid" 
              Grid.Row="0"
              Width="{Binding Path=ActualWidth, ElementName=grid}"
              ItemsSource="{Binding EventTypesCombinerCollection}"
              VerticalAlignment="Stretch"
              HorizontalContentAlignment="Stretch" 
              VerticalContentAlignment="Stretch">
    </ListView>

型号:

public class MainViewModel_Combiner : BindableBase // модель по событиям работы скважины
{
    private Dictionary<string, Dictionary<string, bool>> _eventTypesCombinerCollection;

    /// <summary>
    /// Именованный двумерный массив совмещения мероприятий. Совмещение определяется как EventTypesCombinerCollection["type1"]["type2"]
    /// </summary>
    public Dictionary<string, Dictionary<string, bool>> EventTypesCombinerCollection
    {
        get { return _eventTypesCombinerCollection; }
        set
        {
            _eventTypesCombinerCollection = value;
            OnPropertyChanged("EventTypesCombinerCollection");
        }
    }
    public MainViewModel_Combiner()
    {
        EventTypesCombinerCollection = new Dictionary<string, Dictionary<string, bool>>();
        GenerateEventTypesCocllectionFrameFromDataBase();
    }

    /// <summary>
    /// Заполняет двумерный словать типов мероприятий (абстракция для получения квадратной таблицы с одинаковыми заголовками строк и столбцов)
    /// </summary>
    private void GenerateEventTypesCocllectionFrameFromDataBase()
    {
        var EventTypesList = GetEventTypesList();
        foreach (string eventTypeCombiner in EventTypesList)
        {
            Dictionary<string, bool> combiningItems = new Dictionary<string, bool>(); 
            foreach (string eventTypeCombining in EventTypesList)
            {
                combiningItems.Add(eventTypeCombining, false);
            }
            EventTypesCombinerCollection.Add(eventTypeCombiner, combiningItems);
        }
    }

    /// <summary>
    /// Собирает список типов мероприятий из БД
    /// </summary>
    /// <returns></returns>
    private List<string> GetEventTypesList()
    {
        using (var db = new IP_dbEntities())
        {
            return db.EVENTS_TYPE.Select(e => e.event_type.Trim()).ToList();
        }
    }
}

和 xaml.cs 文件:

public partial class Combiner : Window
{
    public Combiner()
    {
        InitializeComponent();
        CreateDataGridColumns();
    }

    private void CreateDataGridColumns()
    {
        var gridView = new GridView();
        PlanningDataGrid.View = gridView;
        gridView.Columns.Add(new GridViewColumn() { Header = "Тип мероприятия", DisplayMemberBinding = new Binding("Key") }); // Создаем первый столбец
        var eventTypeList = GetEventTypesList();
        foreach (string eventType in eventTypeList)
        {
            var listViewColumn = new GridViewColumn
            {
                Header = eventType,
                DisplayMemberBinding = new Binding("Value[" + eventType + "]"),
                Width = 30,
                CellTemplate = GenerateCellTemplate(eventType),
            };
            gridView.Columns.Add(listViewColumn);
        }
    }

    private DataTemplate GenerateCellTemplate(string eventType)
    {
        var template = new DataTemplate();
        FrameworkElementFactory factory = new FrameworkElementFactory(typeof(CheckBox));
        factory.SetBinding(ToggleButton.IsCheckedProperty, new Binding("Value[" + eventType + "]"));
        template.VisualTree = factory;
        return template;
    }

    /// <summary>
    /// Собирает список типов мероприятий из БД
    /// </summary>
    /// <returns></returns>
    private List<string> GetEventTypesList()
    {
        using (var db = new IP_dbEntities())
        {
            return db.EVENTS_TYPE.Select(e => e.event_type.Trim()).ToList();
        }
    }
}

你知道任何方法,如何解决这个问题,或者做一些新的事情吗?

【问题讨论】:

  • 修复 - 将复选框改为“false”
  • 好的,我会试着检查一下。
  • 非常感谢,这个案子我遇到了很多麻烦
  • 我有一些进展:如果在 xaml.cs 文件中删除行 DisplayMemberBinding = new Binding("Value[" + eventType + "]"), 那么将显示复选框,但是,当然, bindind 将丢失。
  • 在未定义 DisplayMemberBinding 时尝试在 CreateDataGridColumns 方法中创建绑定并将其发送到 GenerateCellTemplate 方法

标签: c# wpf dictionary


【解决方案1】:

非常感谢 StepUp 和 Ilan 的帮助。我只需要删除这一行是代码后面:

DisplayMemberBinding = new Binding("Value[" + eventType + "]"),

所以,有一个解决办法:

    public partial class Combiner : Window
{
    public Combiner()
    {
        InitializeComponent();
        CreateDataGridColumns();
    }

    private void CreateDataGridColumns()
    {
        var gridView = new GridView();
        PlanningDataGrid.View = gridView;
        gridView.Columns.Add(new GridViewColumn() { Header = "Тип мероприятия", DisplayMemberBinding = new Binding("Key") }); // Создаем первый столбец
        var eventTypeList = GetEventTypesList();
        foreach (string eventType in eventTypeList)
        {
            Binding binding = new Binding();
            var listViewColumn = new GridViewColumn
            {
                Header = eventType,
                Width = 30,
                CellTemplate = GenerateCellTemplate(eventType),
            };
            gridView.Columns.Add(listViewColumn);
        }
    }

    private DataTemplate GenerateCellTemplate(string eventType)
    {
        FrameworkElementFactory checkbox = new FrameworkElementFactory(typeof(CheckBox));
        checkbox.SetBinding(ToggleButton.IsCheckedProperty, new Binding("Value[" + eventType + "]") {Mode = BindingMode.TwoWay});
        return new DataTemplate() {VisualTree = checkbox};
    }

    /// <summary>
    /// Собирает список типов мероприятий из БД
    /// </summary>
    /// <returns></returns>
    private List<string> GetEventTypesList()
    {
        using (var db = new IP_dbEntities())
        {
            return db.EVENTS_TYPE.Select(e => e.event_type.Trim()).ToList();
        }
    }
}

【讨论】:

    【解决方案2】:

    您的DataTemplate 看起来不错。试着写:

    factory.SetBinding(ToggleButton.IsCheckedProperty, new Binding(eventType));
    

    工作示例如下代码sn-p:

     FrameworkElementFactory checkbox = new FrameworkElementFactory(typeof(CheckBox));
     checkbox.Name = "aCheckBox";
     checkbox.SetBinding(ToggleButton.IsCheckedProperty, new Binding("YourBoolProperty"));
     DataTemplate dataTemplate = new DataTemplate() { VisualTree = checkbox };
    

    更新:

    要从Dictionary 获取值,您应该使用以下语法:

    Dictionary<int, string> dictionary = new Dictionary<int, string>();
    string str = dictionary[1];
    

    所以你的代码应该是这样的:

    factory.SetBinding(ToggleButton.IsCheckedProperty, new Binding(dictionary[1]));
    

    【讨论】:

    • @ДмитрийРепин 随时提出任何问题
    • 我不能写:factory.SetBinding(ToggleButton.IsCheckedProperty, new Binding(eventType));因为它是字典,而 eventType 是一个键
    • 不幸的是,我有其他类型的字典,我按照您的显示粘贴它
    • @ДмитрийРепин 只需使用调试器来查看您应该如何对待您的Dictionary&lt;Dictionary&lt;string, bool&gt;&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    相关资源
    最近更新 更多