Привязка к TextBox в ListView? - PullRequest
       34

Привязка к TextBox в ListView?

1 голос
/ 15 августа 2011

Я искал ответ на этот вопрос уже почти неделю, и я не могу найти способ сделать это.Я думаю, это относительно простая вещь ...

У меня есть ListView, и один GridViewColumn содержит элементы TextBox.Я хочу поместить Label прямо под ListView, и заполнить его суммой элементов во всех TextBoxes.Всякий раз, когда кто-либо изменяет значение в любом из текстовых полей, сумма также должна меняться.

Я знаю, что мне нужно использовать конвертер, чтобы получить сумму ... но я не знаю, как получить привязкуправильно ...

Любая помощь будет принята с благодарностью!

РЕДАКТИРОВАТЬ: я закончил с этим немного по-другому.Я опубликую свое решение ниже.

<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

Ответы [ 2 ]

1 голос
/ 15 августа 2011

Простое решение (я уверен, что не самое лучшее) состоит в том, чтобы связать

ElementName = myListView, Path = Items

И в элементах обхода конвертера с помощью VisualTreeHelper.GetChild() выяснить базовый TextBlock элемента, а затем int.TryParse(textBlock.Text, out currentItemValue);

0 голосов
/ 17 августа 2011

Я немного разочарован, потому что я действительно надеялся подойти к этому так, как предлагал sllev.Мне это показалось наиболее логичным способом сделать это.Возможно, еще есть способ, но я не нашел его.

Вот как я решил эту проблему.По сути, я добавил столбец «Тот» в мой источник данных (его не было в моем первоначальном решении, хотя в моем вопросе выше).Я привязал свой TextBox к этому столбцу, а затем обновил ListView для события LostFocus TextBox в ListView.Функция Refresh () вызывает повторный вызов SumConverter.

Надеюсь, это поможет кому-то другому - это выглядело как простой запрос, но я потратил на него кучу времени.

MainWindow.xaml:

<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>
        <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 LostFocus="TextBox_LostFocus" Width="100" Text="{Binding XPath='@Tot'}" />
                                </DockPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>    
        </ListView>

        <Label VerticalAlignment="Stretch">
            <Label.Content>
                <MultiBinding Converter="{StaticResource mySumConverter}">
                    <Binding ElementName="myListView" Path="Items"/>
                    <Binding ElementName="myListView" Path="Items.Count"/>
                </MultiBinding>
            </Label.Content>
        </Label>
    </StackPanel>
</Window>

CodeBehind на MainWindow.xaml:

Class MainWindow 

        Public Sub New()
            ' This call is required by the designer.
            InitializeComponent()
        End Sub

        Private Sub TextBox_LostFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            myListView.Items.Refresh()
        End Sub
    End Class

SumConverter.vb:

<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 ItemCollection
        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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...