C#/XAML/WPF 绑定部分工作,仅显示列表中的第一项

Posted

技术标签:

【中文标题】C#/XAML/WPF 绑定部分工作,仅显示列表中的第一项【英文标题】:C#/XAML/WPF binding working partially, only displays first item in List 【发布时间】:2011-06-29 22:38:40 【问题描述】:

我有一个非常简单的绑定,但我看到的问题是,我看到的不是显示三个公司(company_list 是一个列表,其中 Company 包含要绑定的 company_id),而是弹出窗口company_list 中只有 first company_id。我有其他似乎工作正常的绑定,在其他一些情况下,我看到我使用了 ItemSource 而不是 DataContext,但是当我使用它时,我得到“使用 ItemsSource 之前项目集合必须为空”。我在 ***、msdn 和其他地方广泛搜索了这个问题的简单答案,并且看到了大多数我无法理解/应用的非常复杂的解决方案。

当我的窗口出现时,它有:

A公司

它应该在哪里:

A公司 公司B 公司C

这是 company_list 的内容(是的,在调试器中验证)。建议赞赏!代码和 XAML 紧随其后。

    ReadMasterCompanyList();  // populates a_state.company_list with 3 companies
    // display company list dialog
    CompanySelect cs_window = new CompanySelect();
    cs_window.CompanyListView.DataContext = a_state.company_list;
    // fails: cs_window.CompanyListView.ItemsSource = a_state.company_list;
    cs_window.Show();

还有来自 CompanySelect 的 XAML:

<Grid>
    <ListView IsSynchronizedWithCurrentItem="True" 
      x:Name="CompanyListView"
       SelectionMode="Single" SelectionChanged="CompanyListView_SelectionChanged">
        <ListView.ItemContainerStyle>
            <Style TargetType="x:Type ListViewItem">
                <Setter Property="Height" Value="30"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListViewItem Content="Binding Path=company_id"></ListViewItem>
    </ListView>
</Grid>

【问题讨论】:

【参考方案1】:

问题是,您在 XAML 代码中定义了一个 ListViewItem。你不应该这样做。 试试这样的:

<Grid>
    <ListView IsSynchronizedWithCurrentItem="True" 
      x:Name="CompanyListView"
       SelectionMode="Single" SelectionChanged="CompanyListView_SelectionChanged">
        <ListView.ItemContainerStyle>
            <Style TargetType="x:Type ListViewItem">
                <Setter Property="Height" Value="30"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Content=Binding Path=company_id/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

【讨论】:

【参考方案2】:

首先,只在cs_window.Show()之后设置DataContext。

其次,您小时候在 ListView 的 XAML 中拥有的 ListViewItem 是您只看到一个的原因。

第三,如果您在 XAML 中定义 ItemsSource,可能会更好(并且会更类似于 MVVM),如下所示:

<ListView ItemsSource="Binding Path=company_list" ...>

这是在将 a_state 设置为 ListView 的容器或其他祖先元素的 DataContext 之后。

【讨论】:

我能够按照建议在 cs_window.Show() 之后设置 ItemSource。凉爽的!我将按照建议在 XAML 中尝试 ItemsSource;以前尝试过,但当时也有其他问题:-)【参考方案3】:

我会在代码隐藏中设置 ListView 的 ItemsSource,而不是 DataContext:

cs_window.CompanyListView.ItemsSource = a_state.company_list;

或绑定:

<ListView ItemsSource="Binding company_list">

然后改为设置ListView的ItemTemplate。

...
<ListView.ItemTemplate>
  <DataTemplate>
    <TextBlock Text="Binding company_id" />
  </DataTemplate>
</ListView.ItemTemplate>
...

我还会考虑使用 MVVM design pattern 来实现可测试性和关注点分离,并考虑使用 PascalCase 作为您的属性名称。

另外,除非您特别想要 ListView,否则我会使用 ListBox。

【讨论】:

谢谢,这有帮助。请注意,“TextBlock”似乎没有 Content 属性,它是 Text="Binding company_id"。 另外,您为什么建议使用 ListBox 与 ListView?我遇到的一个问题是,既然我的 ListView 出现了所有 3 家公司,第一个被自动选择了 - 我想显示这些公司,默认情况下没有选择它们。 您可以根据需要设置 SelectedItem 属性。 ListView/ListBox 的区别见***.com/questions/227231/…

以上是关于C#/XAML/WPF 绑定部分工作,仅显示列表中的第一项的主要内容,如果未能解决你的问题,请参考以下文章

XAML WPF 的绑定/引用方法

xaml wpf - 渐变画笔资源无法正常工作

XAML/WPF - 里面有 StackPanel 的 ScrollViewer 不滚动

使用SelectByText(部分)与C#Selenium WebDriver绑定似乎不起作用

jqGrid Select 不更新 onchange (C# MVC)

xaml / wpf TabControl如何使用屏幕的100%拉伸