Listview DataTemplate Binding返回错误

时间:2013-09-07 03:57:27

标签: c# wpf xaml

我正试图从Winform切换到WPF,到目前为止,这很痛苦。

无论如何,我试图使用DataTemplate使这个绑定的东西工作。

我有一个班级:

public class TranslatorListItem
{
    public string Item { get; set; }
    public string OriginalMessage { get; set; }
    public string TranslatedMessage { get; set; }
    public string Sector { get; set; }
}

项目添加如下:

TranslatorListItem TLI = new TranslatorListItem();
TranslatorLVI.Items.Add(TLI);

我的XAML DataTemplate:

<DataTemplate x:Key="MyDataTemplate">
    <Border BorderBrush="#FFA4D5E5" BorderThickness="1,1,0,0" Margin="6">
        <StackPanel Margin="6,2,6,2">
            <TextBox Text="{Binding}" TextWrapping="Wrap" BorderThickness="0" BorderBrush="#00000000" />
        </StackPanel>
    </Border>
</DataTemplate>

这就是我试图绑定数据的方法,但是它返回了这个错误:“双向绑定需要Path或XPath。”

    <ListView Margin="23,224,27,54" Name="TranslatorLVI" ItemsSource="{Binding}" HorizontalContentAlignment="Stretch" 
              ItemContainerStyle="{StaticResource MyItemContainerStyle}">
        <ListView.View>
            <GridView AllowsColumnReorder="False">
                <GridViewColumn Header="Item" DisplayMemberBinding="{Binding Path=Item}" CellTemplate="{StaticResource MyDataTemplate}" />
                <GridViewColumn Header="Original Message" Width="300" CellTemplate="{StaticResource MyDataTemplate}" />
                <GridViewColumn Header="Translated Message" DisplayMemberBinding="{Binding Path=TranslatedMessage}" CellTemplate="{StaticResource MyDataTemplate}" />
                <GridViewColumn Header="Sector" DisplayMemberBinding="{Binding Path=Sector}" />
            </GridView>
        </ListView.View>
    </ListView>

我需要TranslatedMessage绑定才能编辑。因此该字段不会是只读的。 我听说我可能需要设置双向绑定,但我不知道该怎么做。

感谢任何帮助。 谢谢!

3 个答案:

答案 0 :(得分:2)

  

我正试图从Winform切换到WPF,到目前为止,这很痛苦。

不,不是。 WPF是人类历史上最好的UI框架。 winforms(或其他任何东西)甚至无法与它进行比较。

你的问题是你在WPF中尝试使用winforms方法但是你失败了。 WPF不支持具有winforms心态的开发人员。

WPF中完全不需要你习惯使用winforms背后的所有可怕代码。

请阅读Rachel's Excellent Answer(和关联的博客文章),了解从winforms升级到WPF时所需的转移。


正如在@ JasRaj的回答中提到的,在这种情况下你错过了DisplayMemberBinding。我测试了你的代码并添加了这样的代码:

<GridViewColumn Header="Original Message" 
                DisplayMemberBinding="{Binding OriginalMessage}"  
                Width="300"/>

它完美无缺。


在第二次阅读您的问题后,我意识到您希望其中一个列可以编辑。

首先,我要说的是,使用ListView is easierDataGrid可以 实现

您需要从DisplayMemberBinding中移除ListView才能使用CellTemplate,因此您需要稍微修改模板:

    <DataTemplate x:Key="MyDataTemplate">
        <Border BorderBrush="#FFA4D5E5" BorderThickness="1,1,0,0" Margin="6">
            <TextBox Text="{Binding TranslatedMessage}" 
                     TextWrapping="Wrap" 
                     BorderThickness="0" 
                     BorderBrush="#00000000" />
        </Border>
    </DataTemplate>

我已将ListViewDataGrid并排放置,以便您进行比较:

enter image description here

这是XAML:

<UniformGrid Columns="2">
    <ListView ItemsSource="{Binding}" HorizontalContentAlignment="Stretch">
        <ListView.View>
            <GridView AllowsColumnReorder="False">
                <GridViewColumn Header="Item" DisplayMemberBinding="{Binding Path=Item}"/>
                <GridViewColumn Header="Original Message" DisplayMemberBinding="{Binding OriginalMessage}"  Width="300"/>
                <GridViewColumn Header="Translated Message" CellTemplate="{StaticResource MyDataTemplate}" />
                <GridViewColumn Header="Sector"/>
            </GridView>
        </ListView.View>
    </ListView>

    <DataGrid ItemsSource="{Binding}"
              AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Item" Binding="{Binding Path=Item}" IsReadOnly="True"/>
            <DataGridTextColumn Header="Original Message" Binding="{Binding OriginalMessage}" IsReadOnly="True" Width="300"/>
            <DataGridTextColumn Header="Translated Message" Binding="{Binding TranslatedMessage}" />
            <DataGridTextColumn Header="Sector" Binding="{Binding Sector}"/>
        </DataGrid.Columns>
    </DataGrid>

</UniformGrid>
  • 请注意ListView需要DataTemplates才能支持版本,默认情况下它是只读的,而DataGrid默认情况下是可编辑的,不需要任何特殊的模板和要求您将IsReadOnly="True"添加到旨在为只读的列。

  • 此外,我注意到您正在使用程序代码手动向ListView添加项目。这在WPF中是不可取的。您必须使用ObservableCollection<>并操纵该集合,并让WPF绑定引擎为您更新UI。

  • 建议并希望您在WPF中Separate logic/data from UI

  • 如果您需要进一步说明,请告诉我。

  • WPF Rocks。

答案 1 :(得分:1)

将Gridview的第二列与OriginalMessage属性绑定。

喜欢: -

DisplayMemberBinding =“{Binding Path = OriginalMessage}”

它应该有用。

答案 2 :(得分:1)

在我看来,你没有完全使用datatemplate。你只是用它来显示一个属性; 实际上,您可以使用DataTemplate显示该类中的所有数据(TranslatorListItem); 比如这个

     <DataTemplate x:Key="MyDataTemplate">
            <Border BorderBrush="#FFA4D5E5" BorderThickness="1,1,0,0" Margin="6">
                <TextBox Text="{Binding Item}" 
                         TextWrapping="Wrap" 
                         BorderThickness="0" 
                         BorderBrush="#00000000" />
                <TextBox Text="{Binding TranslatedMessage}" 
                             TextWrapping="Wrap" 
                             BorderThickness="0" 
                             BorderBrush="#00000000" />
                  ( ..... follow up)
                  </Border>
    </DataTemplate>
So your ListView  can design like this:
 <ListView ItemsSource="{Binding}" HorizontalContentAlignment="Stretch"
  ItemTemplate="{StaticResource MyDataTemplate}"> 
    </ListView>