绑定到 ListView 中的文本框?
我已经寻找这个问题的答案近一周了,但我似乎找不到办法做到这一点。我认为这是一件相对简单的事情...
我有一个 ListView,一个 GridViewColumn 包含 TextBox 项目。我想在 ListView 的正下方放置一个标签,并用所有文本框中的项目总和填充它。每当有人更改任何文本框中的值时,总和也应该更改。
我知道我需要使用转换器来获得总和...但我不知道如何正确绑定...
任何帮助将不胜感激!
编辑:我最终以稍微不同的方式解决了这个问题。我将在下面发布我的解决方案。
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:WpfApplication2"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<XmlDataProvider x:Key="myParties" XPath="Parties" Source="XMLFile1.xml" />
<CollectionViewSource x:Key="myCollectionViewSource" Source="{StaticResource myParties}" />
<converters:SumConverter x:Key="mySumConverter" />
</Window.Resources>
<StackPanel>
<Button x:Name="Breakpoint" Click="bpClick" Content="Breakpoint"/>
<ListView x:Name="myListView"
HorizontalAlignment="Stretch"
ItemsSource="{Binding Source={StaticResource myCollectionViewSource},XPath='Party',Mode=TwoWay}">
<ListView.View>
<GridView>
<GridViewColumn Width="100" DisplayMemberBinding="{Binding XPath='@Contact'}" Header="Contact"/>
<GridViewColumn DisplayMemberBinding="{Binding XPath='@Qty'}" Header="Q"/>
<GridViewColumn DisplayMemberBinding="{Binding XPath='@Amount'}" Header="Amt"/>
<GridViewColumn x:Name="tbTot" Header="Tot">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DockPanel>
<TextBox Width="100" Text="{Binding XPath='@Tot'}" />
</DockPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Label Height="22">
<Label.Content>
<MultiBinding Converter="{StaticResource mySumConverter}">
<Binding ElementName="myListView" Path="Items"/>
<Binding ElementName="myListView" Path="Items.Count"/>
</MultiBinding>
</Label.Content>
</Label>
</StackPanel>
</Window>
XML 文件:
<?xml version="1.0" encoding="utf-8" ?>
<Parties>
<Party Contact="Jim Shmekel"
Qty="1"
Amount="55.00"
Tot="55.00"/>
<Party Contact="Shmi Skywalker"
Qty="1"
Amount="20.00"
Tot="20.00"/>
<Party Contact="Jon Ronson"
Qty="1"
Amount="23.00"
Tot="23.00"/>
</Parties>
SumConverter:
Imports System.Collections.ObjectModel
Imports System.Reflection
<ValueConversion(GetType(Object()), GetType(String))>
Public Class SumConverter : Implements System.Windows.Data.IMultiValueConverter
Public Function Convert(ByVal values() As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert
Static lvItems As IList
Static lvItem As Xml.XmlElement
Dim nVal As Double
Convert = 0
lvItems = values(0)
If lvItems Is Nothing Then Exit Function
For Each lvItem In lvItems
'Debug.Print(lvItem.GetAttribute("Tot"))
If Double.TryParse(lvItem.GetAttribute("Tot"), nVal) Then
Convert = Convert + nVal
End If
Next
End Function
Public Function ConvertBack(ByVal value As Object, ByVal targetTypes() As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack
ConvertBack = Nothing
End Function
End Class
I have been searching for an answer for this for almost a week now, and I can't seem to find a way to do this. I would think it is a relatively simple thing...
I have a ListView, and one GridViewColumn contains TextBox items. I want to put a Label right underneath the ListView, and fill it with the sum of the items in all the TextBoxes. Whenever someone changes a value in any of the TextBoxes, the sum should change, too.
I know I need to use a Converter to get the sum... but I don't know how to get the binding right...
Any help would be greatly appreciated!
EDIT: I ended up solving this in a slightly different way. I will post my solution below.
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:WpfApplication2"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<XmlDataProvider x:Key="myParties" XPath="Parties" Source="XMLFile1.xml" />
<CollectionViewSource x:Key="myCollectionViewSource" Source="{StaticResource myParties}" />
<converters:SumConverter x:Key="mySumConverter" />
</Window.Resources>
<StackPanel>
<Button x:Name="Breakpoint" Click="bpClick" Content="Breakpoint"/>
<ListView x:Name="myListView"
HorizontalAlignment="Stretch"
ItemsSource="{Binding Source={StaticResource myCollectionViewSource},XPath='Party',Mode=TwoWay}">
<ListView.View>
<GridView>
<GridViewColumn Width="100" DisplayMemberBinding="{Binding XPath='@Contact'}" Header="Contact"/>
<GridViewColumn DisplayMemberBinding="{Binding XPath='@Qty'}" Header="Q"/>
<GridViewColumn DisplayMemberBinding="{Binding XPath='@Amount'}" Header="Amt"/>
<GridViewColumn x:Name="tbTot" Header="Tot">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DockPanel>
<TextBox Width="100" Text="{Binding XPath='@Tot'}" />
</DockPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Label Height="22">
<Label.Content>
<MultiBinding Converter="{StaticResource mySumConverter}">
<Binding ElementName="myListView" Path="Items"/>
<Binding ElementName="myListView" Path="Items.Count"/>
</MultiBinding>
</Label.Content>
</Label>
</StackPanel>
</Window>
XML file:
<?xml version="1.0" encoding="utf-8" ?>
<Parties>
<Party Contact="Jim Shmekel"
Qty="1"
Amount="55.00"
Tot="55.00"/>
<Party Contact="Shmi Skywalker"
Qty="1"
Amount="20.00"
Tot="20.00"/>
<Party Contact="Jon Ronson"
Qty="1"
Amount="23.00"
Tot="23.00"/>
</Parties>
SumConverter:
Imports System.Collections.ObjectModel
Imports System.Reflection
<ValueConversion(GetType(Object()), GetType(String))>
Public Class SumConverter : Implements System.Windows.Data.IMultiValueConverter
Public Function Convert(ByVal values() As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IMultiValueConverter.Convert
Static lvItems As IList
Static lvItem As Xml.XmlElement
Dim nVal As Double
Convert = 0
lvItems = values(0)
If lvItems Is Nothing Then Exit Function
For Each lvItem In lvItems
'Debug.Print(lvItem.GetAttribute("Tot"))
If Double.TryParse(lvItem.GetAttribute("Tot"), nVal) Then
Convert = Convert + nVal
End If
Next
End Function
Public Function ConvertBack(ByVal value As Object, ByVal targetTypes() As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object() Implements System.Windows.Data.IMultiValueConverter.ConvertBack
ConvertBack = Nothing
End Function
End Class
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
直接的解决方案(我确信不是最好的)是绑定
And 在转换器中遍历项目并使用 VisualTreeHelper.GetChild() 找出项目的底层 TextBlock,然后 int.TryParse( textBlock.Text, out currentItemValue);
Straightforward solution (I'm sure not the best) is to bind a
And in converter traverse items and using
VisualTreeHelper.GetChild()
find out underlying TextBlock of an item and thenint.TryParse(textBlock.Text, out currentItemValue);
我有点失望,因为我真的希望按照 sllev 建议的方式来解决这个问题。对我来说,这似乎是最合乎逻辑的做法。也许还有办法,但我还没想到。
这就是我最终解决这个问题的方法。基本上我所做的是将“Tot”列添加到我的数据源中(它在我的初始解决方案中不存在,尽管它在我上面的问题中)。我将 TextBox 绑定到该列,然后在 ListView 内 TextBox 的 LostFocus 事件上刷新 ListView。 Refresh() 导致 SumConverter 再次被调用。
希望这可以帮助其他人 - 这似乎是一个简单的请求,但我在上面浪费了很多时间。
MainWindow.xaml:
MainWindow.xaml 上的代码隐藏:
SumConverter.vb:
I'm a bit disappointed, because I really was hoping to approach this the way the sllev had suggested. To me, that seemed like the most logical way of doing it. There may still be a way, but I haven't figured it out.
Here is how I ended up solving this problem. Basically what I did was add the "Tot" column to my DataSource (it was not there in my initial solution although it is in my question above). I bound my TextBox to that column, and then refreshed the ListView on the LostFocus event of the TextBox within the ListView. The Refresh() causes the SumConverter to be called again.
Hopefully this helps someone else out - it seemed like a simple request but I have wasted a ton of time on it.
MainWindow.xaml:
CodeBehind on MainWindow.xaml:
SumConverter.vb: