我正试图从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绑定才能编辑。因此该字段不会是只读的。 我听说我可能需要设置双向绑定,但我不知道该怎么做。
感谢任何帮助。 谢谢!
答案 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 easier,DataGrid
可以 实现 。
您需要从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>
我已将ListView
和DataGrid
并排放置,以便您进行比较:
这是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。
如果您需要进一步说明,请告诉我。
答案 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>