Привязка текстового поля в заголовке datatemplate ListView к свойству фильтра

#wpf #listview #binding #listbox #datatemplate

#wpf #listview #привязка #listbox #datatemplate

Вопрос:

Я создаю настраиваемый заголовок listview, который содержит текст заголовка, но также имеет текстовое поле, которое вы можете ввести для фильтрации содержимого этого столбца. Мой код в настоящее время выглядит следующим образом:

 <UserControl.Resources>
        <DataTemplate x:Key="myHeaderTemplate">
            <StackPanel>
                <TextBlock FontSize="14" Foreground="DarkBlue" Margin="20,4" Text="{Binding}" />
                <TextBox Text="" Margin="4,2" />
            </StackPanel>
        </DataTemplate>
</UserControl.Resources>
  

которое является определением для таблички данных заголовка, содержащей текстовое поле; и listview

 <ListView ItemsSource="{Binding Path=MyData}" IsSynchronizedWithCurrentItem="True">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Last Name" HeaderTemplate="{StaticResource myHeaderTemplate}"
                            DisplayMemberBinding="{Binding Path=Something}" />
            <GridViewColumn Header="First Name" HeaderTemplate="{StaticResource myHeaderTemplate}" 
                            DisplayMemberBinding="{Binding Path=Something}" />
            <GridViewColumn Header="Address" HeaderTemplate="{StaticResource myHeaderTemplate}" 
                            DisplayMemberBinding="{Binding Path=Tube}" />
        </GridView>
    </ListView.View>
</ListView>
  

Я хочу иметь возможность создать инструкцию filter, которую я могу применить к строкам listview, но для этого мне нужно получить данные из каждого текстового поля фильтра в шаблоне заголовка.

Могу ли я каким-либо образом привязать текстовые поля в заголовках к свойствам моей viewmodel? Если нет, есть ли какой-либо другой способ получить текст?

Спасибо за любую помощь.

Ответ №1:

Вы должны быть в состоянии привязать заголовок к свойству, подобному этому:

 <GridViewColumn 
    Header="{Binding LastNameFilter, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" 
    HeaderTemplate="{StaticResource myHeaderTemplate}"
    DisplayMemberBinding="{Binding Path=Something}" />
  

RelativeSource Необходимо, чтобы добраться до DataContext из ListView — вы также могли бы присвоить ему имя и использовать ElementName вместо этого.

Теперь вы можете создать HeaderFilter класс:

 public class HeaderFilter
{
    public string Name { get; set; }
    public string Filter { get; set; }
}
  

Очевидно, вам нужно было бы расширить этот класс, чтобы подключаться к событию, когда Filter изменяется, для выполнения фильтрации.

Поместите свойство для каждого заголовка столбца в объект, который является DataContext для вашего ListView (вероятно, тот же объект, который предоставляет MyData )

 public class SomeClass
{
    ....
    public HeaderFilter LastNameFilter { get; set; }
    ....
}
  

Комментарии:

1. Блестящий ответ, Крисвью, это всего лишь билет. Большое спасибо за отличное объяснение!

2. Крисвью, я пытаюсь то, что вы предложили, и у меня возникают трудности с пониманием инструкции привязки, которую вы использовали выше, в частности, Header=»{Привязка LastNameFilter, RelativeSource={RelativeSource FindAncestor, AncestorType={x: Type ListView}}}»

3. Крисвью, я пытаюсь то, что вы предложили, и у меня возникают трудности с пониманием оператора привязки, который вы использовали выше, в частности, Header =»{Привязка LastNameFilter, RelativeSource={RelativeSource FindAncestor, AncestorType={x: Type ListView}}}» Получает ли этот оператор свойство LastNameFilter datacontext ListView или пытается получить свойство LastNameFilter самого ListView? Должно ли это быть привязкой DataContext. LastNameFilter вместо этого? Спасибо!