【问题标题】:Listview DataTemplate Binding returning an errorListview DataTemplate 绑定返回错误
【发布时间】:2013-09-07 03:57:27
【问题描述】:

我正在尝试从 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 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 绑定是可编辑的。所以该字段不会是只读的。 我听说我可能需要设置双向绑定,但我不知道该怎么做。

感谢任何帮助。 谢谢!

【问题讨论】:

  • 你的列表视图填充了吗?
  • MyDataTemplate TextBox 文本绑定不包含路径。

标签: c# wpf xaml


【解决方案1】:

我正在尝试从 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 实现,但使用DataGrid is easier

您需要从ListView 中删除DisplayMemberBindings 才能使用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 并排放置,以便您进行比较:

这是 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>
    1234563 IsReadOnly="True" 用于只读的列。
  • 另外,我注意到您正在使用程序代码将项目手动添加到 ListView。这在 WPF 中是不需要的。您必须使用 ObservableCollection&lt;&gt; 并操作该集合,并让 WPF 绑定引擎为您更新 UI。

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

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

  • WPF 摇滚。

【讨论】:

  • 您好,感谢您对 WPF 的大力帮助和博客。我一定会很快阅读它们。我想在 OriginalMessage 和 TranslatedMessage 上使用单元格模板。但是,当我像这样绑定它们时: 该值无效,因为它将 Translated 添加到 Original 并显示两者。我将如何解决这个问题?谢谢!
  • @JonJon2244 你需要 2 个单独的 DataTemplates。每列一个。
  • 是的,我现在就是这样做的,但我认为会有更清洁的方法:/
【解决方案2】:

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

喜欢:-

DisplayMemberBinding="{绑定路径=OriginalMessage}"

它应该可以工作。

【讨论】:

    【解决方案3】:

    在我看来,您没有完全使用数据模板。你只是用它来显示一个属性; 事实上你可以使用一个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>
    

    【讨论】:

      猜你喜欢
      • 2019-04-13
      • 2016-11-30
      • 2011-08-16
      • 1970-01-01
      • 2016-09-07
      • 1970-01-01
      • 2016-03-06
      • 2016-11-30
      • 1970-01-01
      相关资源
      最近更新 更多