WPF DataTemplate Триггерная привязка из кода позади - PullRequest
1 голос
/ 09 марта 2020

Я создаю DataTemplates для ListView в коде позади, поскольку количество столбцов неизвестно на момент привязки. Мой метод добавления столбцов в ListView:

    private void FillListView(DataTable table)
    {
        GridView grid = (GridView)lvMain.View;
        var template = FindResource("cellTemplate");

        foreach (DataColumn col in table.Columns)
        {

            var gridColumn = new GridViewColumn()
            {
                Header = col.ColumnName,
                DisplayMemberBinding = new Binding(col.ColumnName)
            };

            gridColumn.CellTemplate = template;
            gridColumn.CellTemplate.Triggers.Add(mouseOverTrigger);
            gridColumn.CellTemplate.Triggers.Add(mouseNotOverTrigger);

            grid.Columns.Add(gridColumn);
        }
        lvMain.ItemsSource = ((IListSource)table).GetList();
    }

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

Как создать DataTemplates, созданный из кода позади , чтобы реагировать на IsMouseOver изменения?

UPD: Я переместил DataTemplate в ресурсы и поместил там объявление триггеров:

    ...    
    <UserControl.Resources>
        <DataTemplate x:Key="cellTemplate" x:Name="cellTemplate">
            <TextBlock x:Name="cellTextBlock" Text="{Binding}"/>
            <DataTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="cellTextBlock" Property="Background" Value="Black"/>
                </Trigger>
                <Trigger Property="IsMouseOver" Value="False">
                    <Setter TargetName="cellTextBlock" Property="Background" Value="White"/>
                </Trigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </UserControl.Resources>
    <ListView x:Name="lvMain" VirtualizingStackPanel.VirtualizationMode="Recycling">
        <ListView.View>
            <GridView>
            </GridView>
        </ListView.View>
    </ListView>
    ...

UPD 2: Мне интересно, почему, но template, объявленный незадолго до того, как l oop будет применен, я не понимаю. Если я добавлю что-то странное в код XAML, например, пусть DataTemplate будет выглядеть следующим образом:

<DataTemplate x:Key="cellTemplate" x:Name="cellTemplate">
        <DataTemplate.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="FontSize" Value="500"/>
            </Style>
        </DataTemplate.Resources>
        <DataTemplate.Triggers>
            ...
        </DataTemplate.Triggers>
        <Grid>
            <TextBlock Text="{Binding}"/>
            <TextBlock>asdfasdfad</TextBlock>
        </Grid>
    </DataTemplate>

Заданное template IS применяется к столбцу, но ни на что не влияет - ни на width равно 500, ни шаблон не состоит из 2 TextBlock с странными текстами ..

Ответы [ 2 ]

1 голос
/ 10 марта 2020

Проблема в моем коде заключается в способе объявления столбца:

    var gridColumn = new GridViewColumn()
    {
        Header = col.ColumnName,
        DisplayMemberBinding = new Binding(col.ColumnName)
    };

DisplayMemberBinding имеет более высокий приоритет, чем CellTemplate: https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.gridviewcolumn.displaymemberbinding?view=netframework-4.8

0 голосов
/ 09 марта 2020

В настоящее время вы пытаетесь привязаться к IsMouseOver в DataContext, а не в элементе управления. Вам нужно добавить источник:

mouseOverTrigger.Binding = new Binding() { Path = new PropertyPath("IsMouseOver"), RelativeSource = RelativeSource.Self };

или использовать Trigger вместо DataTrigger

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...