【问题标题】:Is it possible to make an List<string> a static resource in xaml?是否可以在 xaml 中使 List<string> 成为静态资源?
【发布时间】:2011-06-11 23:32:09
【问题描述】:

如果我想在代码隐藏中绑定诸如组合框之类的东西,我完全没有问题。类似的东西:

List<string> strings = new List<string>();
AddStringsFromDataSourceToList(strings);

comboBox1.ItemSource = strings;

据我所知,在 XAML 中没有快速而肮脏的方法来执行此操作。对于 wpf 因其超级简单的数据绑定而受到的所有赞誉,这种简单的事情在 C# 中似乎要容易得多。有没有比创建 DependencyProperty 包装器并将它们添加为资源更简单的方法,而无需智能感知或所有进入 ObservableCollections 的帮助?我知道这并非不可能,但如果这样一个简单的任务看起来如此深入,我一定会错过一些东西......

编辑:澄清一下,添加动态列表是这里的问题,而不是静态数组。正如许多人所指出的那样,手动添加项目非常容易。

【问题讨论】:

  • WPF 之所以受到赞誉,是因为它可以很好地将逻辑与设计等分开,而不是因为它可以做任何事情。
  • @Disappointment- 这不是太疯狂...当然不是“任何东西”。它是构建应用程序中最常见的任务之一的简单问题。
  • 我知道这并不疯狂;但是一旦你开始自满并按照“我将把这段数据嵌入到 UI 中......”的思路工作,谁知道它会在哪里结束呢?如果我们谈论的“数据”本质上可以被视为 UI 的一部分,例如常见且恒定的下拉选项列表,那么通常是抽象和重用的使用容器。顺便说一句,我不是在攻击你、问题或方法,只是陈述一些事情。

标签: c# wpf xaml data-binding binding


【解决方案1】:
<Window.Resources>
    <x:Array x:Key="strings" Type="sys:String" 
            xmlns:sys="clr-namespace:System;assembly=mscorlib">
            <sys:String>One</sys:String>
            <sys:String>Two</sys:String>
    </x:Array>
    <!-- likewise -->
    <x:Array x:Key="persons" Type="{x:Type local:Person}" 
            xmlns:local="clr-namespace:namespace-where-person-is-defined">
            <local:Person FirstName="Sarfaraz" LastName="Nawaz"/>
            <local:Person FirstName="Prof" LastName="Plum"/>
    </x:Array>
<Window.Resources>


<ComboBox ItemsSource="{StaticResource strings}" />

<ListBox ItemsSource="{StaticResource persons}">
     <ListBox.ItemTemplate>
           <DataTemplate>
               <TextBlock>
                     <Run Text="{Binding FirstName}"/>
                     <Run Text="  "/>
                     <Run Text="{Binding LastName}"/>
               </TextBlock>
           </DataTemplate>
     </ListBox.ItemTemplate>
</ListBox>

【讨论】:

  • 我希望在窗口级别定义 xmlns,例如&lt;Window ... xmlns:sys="clr-namespace..." xmlns:local="clr-namespace:..."&gt; 而不是在数组资源上。这是非常干净可靠的标准 XAML。
  • 请注意,在您的 xaml 中您有 ,但它应该是 。我无法进行编辑,因为它少于 6 个字符。
  • @edhedges:已修复。谢谢。
【解决方案2】:

您是否正在寻找这样的东西:

<ComboBox>
    <ComboBox.ItemsSource>
        <x:Array Type="sys:String" 
             xmlns:sys="clr-namespace:System;assembly=mscorlib">
            <sys:String>One</sys:String>
            <sys:String>Two</sys:String>
        </x:Array>
    </ComboBox.ItemsSource>                
</ComboBox>

如果您只想为列表定义一些项目,请查看 Henk Holterman 的解决方案。顺便说一句,您也可以将数组声明为资源和其他类型。

更新

看来你已经改变了你的问题。但是我现在不明白你的愿望是什么。如果要绑定代码隐藏中的集合,则创建一个返回此集合的公共属性,将 DataContext 设置为公开此属性的对象并在 XAML 中定义一个绑定:

<ComboBox ItemsSource="{Binding NameOfYourCollectionProperty}"...

希望我能正确理解您的问题...

【讨论】:

    【解决方案3】:

    当然有:

    <ComboBox>
        <ComboBoxItem>One</ComboBoxItem>
        <ComboBoxItem>Two</ComboBoxItem>
    </ComboBox>
    

    根据您的目标,还有其他语法几乎一样简单 - 使用资源或内联项目源,或分组数据.. 甚至 xml 数据。不要沮丧地举手,因为您尝试的第一件事并不容易 - 在我看来,wpf 值得学习曲线。

    WPF 之所以受到赞誉,是因为它比 Windows 窗体更容易将视觉效果与行为分开,并且因为它使创建漂亮的视觉效果非常容易得多,而不是因为它可以更容易地做一些琐碎的例子.但是,在这种情况下 - 更容易做一个简单的例子。

    您的编辑您想从哪里提取它们?您不必以任何方式创建依赖属性或可观察的集合。一个简单的列表属性就可以了(在这种情况下,我更喜欢在 xaml 中使用 collectionviewsource)。另外,如果您讨厌 XAML,请不要忘记需要使用所有 XAML。但是,如果您为 WPF 设计而不是不管它,您会发现很多任务(比如这个)很容易。

    【讨论】:

    • 抱歉,我不清楚,但我正在寻找一种添加动态内容的方法(例如从值未知的 List 中)。
    • @Prof Plum 我想我不明白 - 您希望 xaml 保存一个没有代码的静态资源,但您希望这些值是动态的?值将在何处/何时设置?
    • 谢谢,collectionviesource方法涉及什么?如果您知道除 MSDN 之外的任何展示简洁用法的链接,那将非常有帮助。
    【解决方案4】:

    你可以这样做:

        <ComboBox>
            <ComboBoxItem>one</ComboBoxItem>
            <ComboBoxItem>two</ComboBoxItem>
        </ComboBox>
    

    并且还存在用于在例如资源部分中声明(和隐式创建)数据的语法。

    也许您可以指出一个更完整的场景,包括要求和约束?

    【讨论】:

    • 已编辑以显示我真正了解的内容:当列表项未知时。
    • 现在您似乎想将命令式 C# 混合到声明性 XAML 中。如果你只是把函数变成一个属性,你就完成了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    相关资源
    最近更新 更多