Можно ли создать шаблон для GridViewColumn без фиксированной привязки данных? - PullRequest
2 голосов
/ 24 августа 2011

Возможно ли это?

У меня есть ListView, и я хочу создать шаблон для столбцов, чтобы каждый столбец, помеченный как 'cellTextBox', отображался с текстовым полем в нем (а также вызывалTextBox_LostFocus () для события LostFocus).Мне бы очень хотелось использовать один шаблон, а не определять DockPanel и TextBox для каждого столбца.Тем не менее, каждый столбец будет привязан к отдельному столбцу в источнике данных.

Другими словами, я хотел бы использовать «резак печенья» для GridViewColumns, который позволяет мне указывать разные пути привязки для каждогоодин.

Я пробовал что-то подобное (среди прочего), но это не работает.

Есть идеи?

<Page.Resources>
            <DataTemplate x:Key="cellTextBox">
                <DockPanel>
                <TextBox
                        LostFocus="TextBox_LostFocus"
                        Width="100"
                        Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=DisplayMemberBinding}"
                />
                </DockPanel>
            </DataTemplate>
</Page.Resources>
<StackPanel>

        <ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
                  HorizontalAlignment="Stretch" 
                  ItemsSource="{Binding Tables[0]}" 
                  Width="Auto"
                  x:Name="Service_Tasks">

            <ListView.View>
                <GridView>
                    <GridViewColumn Width="120" CellTemplate="{StaticResource cellTextBox}" DisplayMemberBinding={Binding Path=Field1} Header="Field1" />
                    <GridViewColumn Width="120" CellTemplate="{StaticResource cellTextBox}" DisplayMemberBinding={Binding Path=Field2} Header="Field2" />
                    <GridViewColumn Width="120" CellTemplate="{StaticResource cellTextBox}" DisplayMemberBinding={Binding Path=Field3} Header="Field3" />
                    <GridViewColumn Width="120" CellTemplate="{StaticResource cellTextBox}" DisplayMemberBinding={Binding Path=FieldN} Header="FieldN" />
                    <!-- ... other columns ... -->
                </GridView>
            </ListView.View>

        </ListView>
</StackPanel>

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

Imports System.Windows.Markup

Public Class TemplateBuilderExtension : Inherits StaticExtension
    Dim _path As String
    Shared _tagpath As String

    'Private TagPath As String

    Shared Property TagPath As String
        Get
            TagPath = _tagpath
        End Get
        Private Set(ByVal value As String)
            _tagpath = value
        End Set
    End Property

    Property Path As String
        Get
            Path = _path
        End Get
        Set(ByVal value As String)
            _path = value
        End Set
    End Property

    Public Overrides Function ProvideValue(ByVal serviceProvider As System.IServiceProvider) As Object
        TagPath = Path
        Dim resourceExt = New StaticResourceExtension("TemplateBuilder_BaseTemplate")
        'Dim baseTemplate As DataTemplate = DirectCast(resourceExt.ProvideValue(serviceProvider), DataTemplate)
        ProvideValue = DirectCast(resourceExt.ProvideValue(serviceProvider), DataTemplate)
    End Function

    Public Sub New()
        MyBase.new()
    End Sub

    Public Sub New(ByVal Path As String)
        Me.Path = Path
    End Sub
End Class

Public Class TemplateBuilderTagExtension : Inherits MarkupExtension
    Public Sub New()
        MyBase.New()
    End Sub
    Public Overrides Function ProvideValue(ByVal serviceProvider As System.IServiceProvider) As Object
        ProvideValue = New Binding(TemplateBuilderExtension.TagPath)
    End Function
End Class

Очевидно, что XAML одинаков, независимо от того.

Не забудьте добавить следующую ссылку на пространство имен к тегу корневого уровня:

xmlns:me="clr-namespace:WpfApplication1", заменив WpfApplication на любое корневое пространство имен вашего приложения (это можно найти в свойствах вашего приложения).

Спасибо еще раз @HB!

1 Ответ

4 голосов
/ 24 августа 2011

Единственный метод, о котором я могу подумать сейчас, это встроить markup-extensions , когда вы пытаетесь передать более одного значения одному свойству.

Получение переменных данных вТем не менее, шаблон кажется нетривиальным, и следующий подход с использованием статического свойства довольно полезен, может быть, вы можете придумать что-нибудь получше:получить ресурс, но, к сожалению, он не попал в ProvideValue тега, это был бы лучший способ пересечь путь.

Конечно, вы могли бы динамически создавать шаблон с нуля в TemplateBuilderExtension таким образом вы не столкнетесь с такими проблемами.

...