【问题标题】:WPF databinding to ObservableCollection - ItemTemplate not changing displayed valueWPF 数据绑定到 ObservableCollection - ItemTemplate 不更改显示值
【发布时间】:2017-09-27 11:13:50
【问题描述】:

我正在尝试让 WPF ListView 上的数据绑定正常工作,但无论出于何种原因,无论我尝试了什么,它都将始终使用 ToString 提供的值。

按原样,我有以下内容:

private Controllers.ListController controller;
public ListTest( )
{
    // ...
    listView.DataContext = controller;
}
private void Page_Loaded( object sender, RoutedEventArgs e )
{
    var t = new Task( ( ) =>
    {
        // some work to obtain data using controller...
        Dispatcher.Invoke( ( ) =>
        {
            listView.ItemsSource = controller.TestListSource;
        } );
    } );

    t.Start( );
}

这成功地将ListView 绑定到控制器提供的数据,列表视图将显示IEnumerable<TestListEntry> 中的每个条目。问题是,我似乎无法更改ListView 显示每一行的方式。 TestListEntry如下:

public class TestListEntry
{
    public string GivenName
    {
        get; set;
    }

    public string FamilyName
    {
        get; set;
    }

    public string DisplayName
    {
        get
        {
            return $"{ FamilyName }, { GivenName }";
        }
    }
}

我最初尝试像这样设置ListBox.ItemTemplate

<ListView Grid.Row="2" x:Name="listView">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding DisplayName}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="test" />
        </GridView>
    </ListView.View>
</ListView>

但这并没有改变任何东西。打开 WPF 绑定调试也没有显示任何错误,但确实显示了一些看似无关的内容

System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'ListViewItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=VerticalContentAlignment; DataItem=null; target element is 'ListViewItem' (Name=''); target property is 'VerticalContentAlignment' (type 'VerticalAlignment')

我还尝试在ItemTemplate 内部的TextBlock 上设置背景颜色,它也没有改变任何东西,所以不确定那里发生了什么。然后我尝试设置DisplayNamePathSelectedValuePath

<ListView ItemsSource="{Binding}" Grid.Row="2" x:Name="researcherListView" DisplayMemberPath="DisplayName" SelectedValuePath="DisplayName">

这也没有改变任何东西。我知道我可以更改 ToString 来解决这个问题,但我觉得我只是错过了一些东西......

【问题讨论】:

  • @mm8 是的,确实如此。它被实现为 ObservableCollection&lt;TestListEntry&gt; 虽然
  • 我使用ListBox.ItemTemplate 测试了您的代码,它运行良好。您是否为ListBoxTextBlockTestListEntry 设置了任何隐式样式或模板? (这也可以解释System.Windows.Data Information 消息。)如果不是,请隔离问题并发布Minimal, Complete, and Verifiable example,以便我们找到罪魁祸首。
  • @haindl 道歉,我正在设置 ListView.View 并忘记将其包含在我的答案中。可以通过设置DisplayMemberBinding="{Binding DisplayName}" 来修复 - 为什么?如果您设置,每列是否从ListView.Views GridViewColumn 继承其绑定?

标签: c# wpf listview data-binding


【解决方案1】:

如果您在&lt;ListView.View&gt; 中使用&lt;GridView&gt;,您需要告诉&lt;GridViewColumn&gt; 如何在生成的单元格中显示其TestListEntry 的内容。如果您不这样做,那么.ToString() 是唯一可能的方法,因为这是每个对象拥有的唯一信息。
仅使用 &lt;ListBox.ItemTemplate&gt; 是不够的,因为它对特定列一无所知。

要控制显示的内容,您可以直接设置绑定,就像您在评论中提到的那样:

<GridViewColumn Header="test" DisplayMemberBinding="{Binding Path=DisplayName}" />

或者您可以使用您的&lt;DataTemplate&gt; 设置&lt;GridViewColumn.CellTemplate&gt;

<GridViewColumn Header="test">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding DisplayName}" />
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

如果您想为单元格设置样式而不仅仅是显示文本,那么使用&lt;DataTemplate&gt; 肯定是更好的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2012-11-10
    • 2011-06-08
    • 1970-01-01
    • 2013-10-14
    相关资源
    最近更新 更多