【问题标题】:Databinding: using the static resource (assigning programatically?) DataGrid数据绑定:使用静态资源(以编程方式分配?)DataGrid
【发布时间】:2010-01-26 22:56:20
【问题描述】:

如果我解释一下为什么我需要这样做会更好。

这不是真实的例子,但在我的工作解决方案中,用户将从这样的关系组开始:

苹果 -> 红色 香蕉 -> 黄色

在应用程序中,在不同的屏幕(例如添加水果和添加颜色)中,它们可以添加新的水果/颜色。然后他们需要在我在这里构建的这个屏幕中链接这些,还需要能够改变关系。因此,我无法在 xaml 中定义硬编码列表,因为用户可以更改它。所以我需要加载这个列表,然后在 Comboboxes 中显示它。到目前为止,以下解决方案都无法实现这一目标。

对以下上下文中的 StaticResource 有疑问:

<toolkit:DataGridTextColumn Header="Name"
         Binding="{Binding Name}"
         Width="5*" />

<toolkit:DataGridComboBoxColumn Header="Color"
         ItemsSource="{Binding Source={StaticResource AllColors}}"
         SelectedValueBinding="{Binding Path=Color}"
         TextBinding="{Binding Path=Color}"
         Width="5*" />

AllColors 将被定义为:

<x:Array x:Key="AllColors"
         Type="sys:String">
    <sys:String>Orange</sys:String>
    <sys:String>Yellow</sys:String>
</x:Array>

除了我真正想做的是以编程方式将 StaticResource 设置为字符串列表或数组。

那我该怎么做呢?

谢谢。

编辑 1

这是我尝试过的:

        // find resource object

        //var resource = (string[])Resources["Colors"];
        var i = 0;
        var colors = new string[] { };

        foreach (var fruit in fruitList)
                        {
                            colors[i] = fruit.Color;
                            i++;
                        }

        Resources["Colors"] = colors;

没用。

请帮忙。

编辑 2: 我的完整代码 - 应该让我更清楚地了解我如何以编程方式定义资源

<UserControl x:Class="Wpf.Screen"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit" xmlns:Wpf="clr-namespace:Wpf" MinHeight="300" MinWidth="300" Loaded="Screen_Loaded"
    Name="Fruits">

<GroupBox>
            <toolkit:DataGrid Name="dgFruits" 
            AutoGenerateColumns="False"
            Margin="10"
            ItemsSource="{Binding}">

                <toolkit:DataGrid.Columns>

                    <toolkit:DataGridTextColumn
                        Binding="{Binding Name}"
                        Header="Fruit Name"
                        Width="5*"/>

                    <toolkit:DataGridComboBoxColumn Header="Color"
                                         ItemsSource="{Binding Source={StaticResource AllColors1}}"
                                        SelectedValueBinding="{Binding Path=Color}"
                                        TextBinding="{Binding Path=Color}"
                                        Width="5*" />

                </toolkit:DataGrid.Columns>
            </toolkit:DataGrid>

        </GroupBox>

C#:

namespace Wpf
{
    public partial class Screen

public ObservableCollection<Fruit> FruitCollection { get { return fruitCollection; } }

    public Screen()
        {
            LoadFruitFile(); //this loads fruit into ObservableCollection<Fruit> fruitCollection             
            InitializeComponent();
        }

private void Screen_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {

            var i = 0;
            var colors = new string[] { };

            foreach (var fruit in fruitList)
            {
                colors[i] = fruit.Color;
                i++;
            }

            // define resource in the code
            Resources["AllColors1"] = colors;
            // show new values
            var resource = (string[])Resources["AllColors1"];
            if (resource != null)
                foreach (var item in resource)
                    Console.WriteLine(item);


            dgFruits.ItemsSource = FruitCollection;


}

【问题讨论】:

  • 似乎是一个相当普遍的数据绑定需求,不明白为什么这么难实现!
  • 您能解释一下为什么进行静态绑定很重要吗?为什么不绑定到代码隐藏文件中的属性?
  • 如果我能弄清楚该怎么做就好了。我可以绑定到 List 或在代码隐藏中创建 ObservableCollection 并绑定到其中任何一个,但我不知道如何在代码隐藏中做到这一点。

标签: c# wpf data-binding datagrid


【解决方案1】:

您可以使用 FindResource 方法或 FrameworkElement 的 Resources 属性从代码中获取资源对象。检查以下代码是否适合您:

// find resource object
//string[] resource = (string[])FindResource("AllColors");
string[] resource = (string[])Resources["AllColors"];
if (resource != null)
{
    // old values
    foreach (var item in resource)
        Console.WriteLine(item);
    // set new values
    Resources["AllColors"] = new string[] { "red", "blue", "green"};
}
// find resource and show its new values
resource = (string[])Resources["AllColors"];
if (resource != null)
    foreach (var item in resource)
        Console.WriteLine(item);

虽然我不认为它会按照您想要的方式工作,或者它是您任务的正确解决方案。你可以做的是定义一个带有颜色集合的类:

public class TestColors
{
    public TestColors()
    {
        Colors = new ObservableCollection<string>();
        Colors.Add("red");
        Colors.Add("blue");
        Colors.Add("green");
    }

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

在您的 xaml 中,您可以定义给定对象类型的 ObjectDataProvider 并将您的控件绑定到其 Colors 属性。像这样的:

...
xmlns:local="clr-namespace:YourNamespace"
...
<Window.Resources>
     <ObjectDataProvider x:Key="AllColors0" ObjectType="{x:Type local:TestColors}"/>
</Window.Resources>
...
<ListBox ... 
     DataContext="{StaticResource AllColors0}"
     ItemsSource="{Binding Colors}"/>
...

另一种方法是将控件绑定到窗口的属性,就像这样:

public partial class MainWindow : Window
{
    public static string[] TestProperty
    {
        get
        {
            List<string> result = new List<string>();
            result.Add("red");
            result.Add("green");
            result.Add("blue");
            return result.ToArray();
        }
    }

    public MainWindow()
    {
        InitializeComponent();
     ...

xaml:

<ListBox ...
         ItemsSource="{x:Static local:MainWindow.TestProperty}"/>

update0:在代码中定义资源

// define resource in the code
Resources["AllColors1"] = new string[] { "red1", "blue1", "green1" };
// show new values
resource = (string[])Resources["AllColors1"];
if (resource != null)
    foreach (var item in resource)
        Console.WriteLine(item);

希望这会有所帮助,问候

【讨论】:

  • 到目前为止尝试了您的第一个和最后一个建议。首先没有工作,它找不到 AllColors。找不到名为“{AllColors}”的资源。资源名称区分大小写。标记文件“Wpf;component/screen.xaml”第 48 行第 41 行中的对象“System.Windows.Data.Binding”出错。第二个不起作用我收到此错误:调用的目标已引发异常。标记文件“Wpf;component/screen.xaml”第 48 行位置 41 中的对象“Microsoft.Windows.Controls.DataGridComboBoxColumn”出错。
  • AllColors 是在哪里声明的?尝试将其移至 xaml 的 Window.Resources 部分。我实际上已经测试了提供的代码,它对我有用。但正如我之前建议的那样;这不是这样做的方式;看看建议 #2 或 #3 是否适合您
  • 查看 update0 中的代码以获得我的原始答案会有所帮助;您需要在访问它们之前定义资源
  • 很远,数字 #2 也不起作用,因为这是在用户控件而不是窗口内...
  • 仍然找不到更新代码的资源你能告诉我你需要什么 xaml 才能在你的示例中工作
猜你喜欢
  • 1970-01-01
  • 2010-12-20
  • 2023-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
  • 2012-03-14
  • 1970-01-01
相关资源
最近更新 更多