【问题标题】:ListBox.ItemsSource binding in code and in xaml代码和 xaml 中的 ListBox.ItemsSource 绑定
【发布时间】:2010-09-02 07:06:11
【问题描述】:

我写了简单的代码,比如

public ObservableCollection<string> Names …
public Window1()
{
    PutInDataIntoNames();
    InitializeComponent();
    this.listBox1.ItemsSource = Names;
}

在 xaml 中

<Grid>
    <ListBox Margin="10,11,10,16"
         Name="listBox1"
         Background="Black" 
         Foreground="Orange" 
         />
</Grid>

然后我想在 xaml 中设置 ItemsSource 属性。为了做到这一点,我写了以下内容:

ItemsSource="{Binding Path=Names}"

不幸的是,它不起作用。你能解释一下为什么以及如何做到这一点吗?

【问题讨论】:

    标签: wpf listbox itemssource


    【解决方案1】:

    如果您只指定绑定路径,绑定引擎将尝试从当前的DataContext 开始导航路径,因此ItemsSource="{Binding Path=Names}" 不能像这样工作,有很多不同的事情需要记住,尤其是在做的时候更复杂的事情。

    DataBinding 新手应该阅读的最重要的一篇文章是Data Binding Overview on MSDN

    要返回到您的绑定,如果您想完全在 XAML 中完成它,您也可以这样做,您只需要以某种方式将 Window 设为您的源代码,或者直接或相对地引用它,或者将它设置为数据上下文。

    1 - 直接参考:

    <Window Name="Window"
            ...>
        <Grid> 
                <ListBox ...
                         ItemsSource="{Binding ElementName=Window, Path=Names}"
                         .../>
        </Grid>
    </Window>
    

    2 - 相对参考

        <Grid> 
                <ListBox ...
                         ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Names}"
                         .../>
        </Grid>
    

    3 - 设置 DataContext

    <Window ...
            DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
        <Grid> 
                <ListBox ...
                         ItemsSource="{Binding Path=Names}"
                         .../>
        </Grid>
    </Window>
    

    【讨论】:

    • 这应该是选择的答案。一个难以找到的元素是源的 XAML 绑定必须在 Window 实例中表示的方式:DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"。它是 C#DataContext = this 的 XAML 等价物,但值得它自己的解释,这在网上很难找到(而且显然从 MSDN 文档中丢失,所有示例都基于a source being a resource,从不在代码中创建的 CLR 对象上 -后面)。
    【解决方案2】:

    在后面的代码中执行此操作

    public Window1() 
    { 
        PutInDataIntoNames(); 
        InitializeComponent(); 
        DataContext = this;
    } 
    

    在 XAML 中

    <Grid> 
        <ListBox ItemsSource="{Binding Names}"
             Margin="10,11,10,16" 
             Name="listBox1" 
             Background="Black"  
             Foreground="Orange"   
             /> 
    </Grid>
    

    理想情况下,您应该遵循 MVVM 设计来将数据与背后的代码隔离。

    【讨论】:

    • 好的。但我更喜欢用 xaml 编写它,例如 有时我不需要显式设置 DataContext 而有时我必须这样做,这常常有点令人失望。
    【解决方案3】:

    看来您的Names 可能是一个字段。您只能绑定到公共属性

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-10
      • 1970-01-01
      • 2019-06-07
      相关资源
      最近更新 更多