将C#WPF控件绑定到字典

时间:2011-09-28 23:21:09

标签: c# wpf binding dictionary

嗨:)我只是在学习C#和WPF,我需要编写一个工具:

  1. 加载数据文件(字符串Key,int Value)
  2. 将数据绑定到WPF UI以进行编辑
  3. 保存新数据文件
  4. 我的想法是字典最好。 数据仅从文件加载一次,并且仅使用WPF控件进行更改。 我尝试过很多东西,但是当我将数据绑定到控件时,我仍然会遇到障碍。 我一直在使用该工具的简化版本 - 下面。 数据绑定到WPF控件 - 但更新字典没有更改事件。 我没有找到一个很好的例子。 有人可以解释如何更新字典吗? 战略是正确的吗? - 使用字典 - 使用DataContext。 如果您想查看完整的项目和用户界面 - 底部有一个链接。 我已经工作了很多天......虽然进步但我太慢了;) 干杯 丹尼

    MainWindow.xaml

    <Window x:Class="configGen.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="150">
    <StackPanel Margin="20" Width="80">
        <TextBox Text="{Binding [item1]}" />
        <TextBlock Text="{Binding [item1]}" />
        <TextBox Text="{Binding [item2]}" />
        <TextBlock Text="{Binding [item2]}" />
        <TextBox Text="{Binding [item3]}" />
        <TextBlock Text="{Binding [item3]}" />
        <Slider Value="{Binding [item4]}" Minimum="0" Maximum="256" />
        <TextBlock Text="{Binding [item4]}" />
    </StackPanel>    
    

    MainWindow.xaml.cs

    namespace configGen
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                dataClass record = new dataClass();
                DataContext = record.generate();
            }
        }
    
        public class dataClass
        {
            public Dictionary<string, int> generate()
            {
                Dictionary<string, int> _data = new Dictionary<string, int>();
                _data.Add("item1", 100);
                _data.Add("item2", 120);
                _data.Add("item3", 140);
                _data.Add("item4", 160);
                return _data;
            }
        }
    }
    

    链接到完整项目...

    http://www.baytower.ca/btsRV7config.zip


    感谢大家的所有好评! 我将重新开始工作:)

4 个答案:

答案 0 :(得分:1)

我没有使用词典作为DataContext,而是创建了像MainViewModel这样的自定义对象。给它对应于item1,item2等的属性,除了给它们指定适当的名称。然后使用<TextBox Text="{Binding MyPropertyName}" />。要处理更新,您可以将DataContext设置为新的MainViewModel对象,也可以将类设置为广播属性更改。您可以通过课程中的INotifyPropertyChangeddependency properties来完成此操作。

至少那就是你想要完成的事情。如果你要显示任意数量的控件,你需要不同的东西。

答案 1 :(得分:1)

字典绝对不是在WPF中进行双向数据绑定的便捷方式。似乎ObservableCollection更适合您的要求。

类似的东西:

public class ItemsList : ObservableCollection<Item>
{
    public ItemsList() : base()
    {
        Add(new Item("item 1", 100));
        Add(new Item("item 2", 120));
        Add(new Item("item 3", 140));
        Add(new Item("item 4", 160));
    }
  }

Item是一个带有名称和值属性的简单类。我在这里省略了它,因为它是自我解释的。

这里的优势在于您可以绑定动态数量的项目,而不仅仅是那些必须声明的项目。

将datacontext绑定到它后,您将获得双向数据绑定的自动属性通知。

您的XAML必须更改以适应与课程集合的绑定。也许ItemsControl将该集合作为其ItemsSource

答案 2 :(得分:1)

这是我如何做的一个例子。

主类(代码背后)

 /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private List<MyObject> _myObjects;
        public List<MyObject> MyObjects
        {
            get { return _myObjects; }
            set 
            {
                _myObjects = value;
                if(PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("MyObjects"));
                }
            }
        }


    public MainWindow()
    {
        MyObjects = new List<MyObject>();

        // Add 20 records for sample data
        for (int i = 0; i < 20; i++)
        {
            MyObject o = new MyObject();
            o.Label = string.Format("Key{0}", i);
            o.MyValue = string.Format("Value{0}", i);    
            MyObjects.Add(o);
        }
        InitializeComponent();
        DataContext = this;
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

中学班级

public class MyObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string _label;
    public string Label
    {
        get { return _label; }
        set
        {
            _label = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Label"));
            }
        }
    }

    private string _myValue;
    public string MyValue
    {
        get
        {
            return _myValue;
        }
        set
        {
            _myValue = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("MyValue"));
            }
        }
    }
}

XAML文件

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate x:Key="listboxstyle">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding Path=Label}" />
                <TextBox Grid.Column="1" Text="{Binding Path=MyValue}" />
            </Grid>
        </DataTemplate>
    </Window.Resources>
    <Grid>       

        <ListBox
            ItemsSource="{Binding Path=MyObjects}"
            ItemTemplate="{StaticResource listboxstyle}"
            />

    </Grid>
</Window>

答案 3 :(得分:0)

我尝试了tsell的例子,在列表中使用他的类。该列表只是生成和管理固定数量元素的便捷方式。 Item1 WPF控件绑定到Item1对象及其值。该对象由其索引号找到。在这种情况下,绑定和dataContext很简单,我可以使用(作为初学者)。它有效,但我不确定这是一种优雅的方式。

public MainWindow()
{
    MyObjects = new List<MyObject>();

    MyObject item1 = new MyObject();
    item1.MyValue = string.Format("100");
    MyObjects.Add(item1);

    MyObject item2 = new MyObject();
    item2.MyValue = string.Format("120");
    MyObjects.Add(item2);

    MyObject item3 = new MyObject();
    item3.MyValue = string.Format("140");
    MyObjects.Add(item3);

    MyObject item4 = new MyObject();
    item4.MyValue = string.Format("160");
    MyObjects.Add(item4);

    InitializeComponent();
    DataContext = this;
}

XAML

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel Margin="20" Width="80">
        <TextBox Text="{Binding MyObjects[0].MyValue}" />
        <TextBlock Text="{Binding MyObjects[0].MyValue}" />
        <TextBox Text="{Binding MyObjects[1].MyValue}" />
        <TextBlock Text="{Binding MyObjects[1].MyValue}" />
        <TextBox Text="{Binding MyObjects[2].MyValue}" />
        <TextBlock Text="{Binding MyObjects[2].MyValue}" />
        <Slider Value="{Binding MyObjects[3].MyValue}" Minimum="0" Maximum="256" />
        <TextBlock Text="{Binding MyObjects[3].MyValue}" />
    </StackPanel>
</Window>

顺便说一句,我将为MyValues更改为int ..他们都是int数字。现在它是一个字符串。