Триггер данных не работает внутри списка просмотра WPF - PullRequest
0 голосов
/ 27 апреля 2020

Я не очень знаком с комплексным связыванием WPF, и со вчерашнего дня я не могу понять, как связать значение из моего кода с помощью DataContext внутри DataTrigger кнопки внутри ListView.

I попробуйте сделать это, потому что Я хочу скрыть свои кнопки действий (редактировать / удалить) в каждой строке элементов списка . Поэтому я должен проверить у класса «Пользователь» его атрибуты role и переключить видимость кнопок.

Я выделил множество тем на тему «wpf binding datacontext» и попробовал также множество потенциальных решений. но ничего не получится.

Вот решение, которое я сохранил, потому что, когда я ставлю точку останова на свой DataContext, я вижу все значения внутри.

Код позади .cs:

        public User _user { get; set; }
        public ObservableCollection<Item> MyItems { get; set; }
        public MyWindow(User user)
        {
            InitializeComponent();
            _user = user;
            DataContext = _user; 
            listItems.ItemsSource = GetItemsList();         
        }

MyWindow.xaml:

 <ListView x:FieldModifier="public" ItemsSource="{Binding MyItems}" Margin="10" Name="listItems" BorderThickness="2" BorderBrush="Black" Style="{StaticResource MaterialDesignListView}">
                        <ListView.View>
                            <GridView x:Name="gridViewItem">
                                <GridViewColumn Width="100" DisplayMemberBinding="{Binding Name}">
                                    <GridViewColumn.Header>
                                        <GridViewColumnHeader Cursor="Hand" Tag="Name">Name</GridViewColumnHeader>
                                    </GridViewColumn.Header>
                                </GridViewColumn>
                                <GridViewColumn Width="180" DisplayMemberBinding="{Binding StartHour}">
                                    <GridViewColumn.Header>
                                        <GridViewColumnHeader Cursor="Hand" Tag="StartHour">StartHour</GridViewColumnHeader>
                                    </GridViewColumn.Header>
                                </GridViewColumn>
                                <GridViewColumn Width="180" DisplayMemberBinding="{Binding EndHour}">
                                    <GridViewColumn.Header>
                                        <GridViewColumnHeader Cursor="Hand" Tag="EndHour">EndHour</GridViewColumnHeader>
                                    </GridViewColumn.Header>
                                </GridViewColumn>                                
                                <GridViewColumn Width="180">
                                    <GridViewColumn.Header>
                                        <GridViewColumnHeader Cursor="Hand" Tag="Actions">Actions</GridViewColumnHeader>
                                    </GridViewColumn.Header>
                                    <GridViewColumn.CellTemplate>
                                        <DataTemplate>
                                            <StackPanel Orientation="Horizontal" Name="ActionButtonList">                                   
                                                <Button Click="Delete_Click" x:Name="delete_button" BorderBrush="{x:Null}" Tag="{Binding Id}" Background="White" Margin="0" HorizontalAlignment="Left">
                                                    <materialDesign:PackIcon Kind="Trash" Foreground="Black" Width="15" Height="15" />
                                                    <Button.Style>
                                                        <Style TargetType="{x:Type Button}">
                                                            <Setter Property="Visibility" Value="Visible"/>
                                                            <Style.Triggers>
                                                                <DataTrigger Binding="{Binding DataContext.Role}" Value="User">
                                                                    <Setter Property="Visibility" Value="Collapsed"/>
                                                                </DataTrigger>
                                                            </Style.Triggers>
                                                        </Style>
                                                    </Button.Style>
                                                </Button>
                                            </StackPanel>
                                        </DataTemplate>
                                    </GridViewColumn.CellTemplate>
                                </GridViewColumn>
                            </GridView>
                        </ListView.View>
                    </ListView>

User.cs:

public partial class User
    {       
        public User()
        {}

        public int Id { get; set; }


        public string Role { get; set; }

    }

Ошибка отладки: System. Windows .Data Ошибка: 40: Ошибка пути BindingExpression: свойство DataContext не найдено в 'объекте' '' MyItem_90931F6CDC904A032778416D7F3A5FB410232AF48F7B7245FOE8D783347E9ED5 '(HashCode = 34262603)'. BindingExpression: Path = DataContext.Role; DataItem = 'MyItem_90931F6CDC904A032778416D7F3A5FB410232AF48F7B7245FOE8D783347E9ED5' (HashCode = 34262603); Целевым элементом является «Кнопка» (Имя = ''); Свойство target - «NoTarget» (тип «Object»)

Я думаю, что проблема вызвана неоднозначным использованием DataContext, он распознает внутренний DataContext объекта ListView, а не внешний, из код позади.

Спасибо за ваше внимание и вашу помощь

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

Наконец-то я это сделал, решение было довольно простым: мой код хорош, но проблема была в моем Window XAML, мне пришлось установить имя для моего окна, тогда в моем DataTrigger это выглядит так:

<Button Click="Delete_Click" x:Name="delete_button" BorderBrush="{x:Null}" Tag="{Binding Id}" Background="White" Margin="0" HorizontalAlignment="Left">
                                                    <materialDesign:PackIcon Kind="Trash" Foreground="Black" Width="15" Height="15" />
                                                    <Button.Style>
                                                        <Style TargetType="{x:Type Button}">
                                                            <Setter Property="Visibility" Value="Visible"/>
                                                            <Style.Triggers>
                                                                <DataTrigger Binding="{Binding ElementName=CertifWindow,Path=DataContext.Role}" Value="User">
                                                                    <Setter Property="Visibility" Value="Collapsed"/>
                                                                </DataTrigger>
                                                            </Style.Triggers>
                                                        </Style>
                                                    </Button.Style>
                                                </Button>

Надеюсь, это кому-нибудь поможет

0 голосов
/ 27 апреля 2020

Это не двусмысленно, DataContext не существует на том уровне, на котором вы его запросили. Что вы должны сделать.

  • Создать класс с именем MyWindowViewModel
  • Этот класс должен иметь как User, так и MyItems в качестве свойств
  • Установить MyWindow.DataContext равным MyWindowViewModel (не установите ItemsSource в коде позади)
  • В коде xaml оставьте привязку ItemsSource к MyItems
  • Замените [Binding = "{Binding DataContext.Role}"] чем-то вроде ["{Binding Path = DataContext.User.Role, RelativeSource = {RelativeSource Mode = FindAncestor, AncestorType = Window}} "]

Вам также следует подумать об использовании Icommand вместо события click и кода позади, и если вы просто отключаете кнопка вместо скрытия это нормально, вы используете ICommand для этого (см. https://www.c-sharpcorner.com/UploadFile/20c06b/icommand-and-relaycommand-in-wpf/)

...