2017-09-27 77 views
0

我试图让WPF ListView上的数据绑定能够正常工作,但无论出于何种原因,它总是会使用ToString提供的值,而不管我尝试过什么。WPF数据绑定到ObservableCollection - ItemTemplate不改变显示的值

由于是,我有类似如下:

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') 

我也试着设置里面ItemTemplateTextBlock背景颜色,并没有任何改变什么,所以不知道那里发生了什么。然后我试图设置DisplayNamePathSelectedValuePath

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

这并不会改变任何事情。我知道我可以改变ToString来解决这个问题,但我有一种感觉,我只是失去了一些东西......

+0

@ mm8是的,它的确如此。它被实现为'ObservableCollection '尽管 – Mythrillic

+0

我使用ListBox.ItemTemplate测试了你的代码,它完美的工作。你有任何为ListBox,TextBlock或TestListEntry设置的隐式样式或模板吗? (这也可以解释'System.Windows.Data Information'消息。)如果不是,请隔离问题并发布[最小,完整和可验证示例](https://stackoverflow.com/help/mcve)我们可以找到罪魁祸首。 – haindl

+0

@haindl道歉,我在设置ListView.View,并忘记将它包含在我的答案中。可以通过设置DisplayMemberBinding =“{Binding DisplayName}”来解决这个问题 - 为什么?如果您设置了每列是否从ListView.View的'GridViewColumn'继承它们的绑定? – Mythrillic

回答

1

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

为了控制所显示的内容,您可以直接设置绑定,就像你在您的评论中提到:

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

,也可以使用设置<GridViewColumn.CellTemplate><DataTemplate>

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

使用<DataTemplate>肯定会是更好的解决方案,如果你想让你的单元格不仅仅是显示文本而更多一些。

相关问题