I'm not very familiar with WPF complex binding and since yesterday I cant figure out how to bind a value from my code behind with "DataContext" inside a DataTrigger of a button inside a ListView.
I try to do that because I want to hide my actions buttons (edit/delete) of each row of my listview items. So I have to check from a "User" class, the role attribute of it and toggle the visibility of the buttons.
I red lots of topics on "wpf binding datacontext", and tried also tons of potential solution but nothing succeed.
Here is the solution that i kept because when I put a breakpoint on my DataContext I can see all the values inside.
Code behind .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; }
}
The debug error : System.Windows.Data Error: 40 : BindingExpression path error: 'DataContext' property not found on 'object' ''MyItem_90931F6CDC904A032778416D7F3A5FB410232AF48F7B7245FOE8D783347E9ED5' (HashCode=34262603)'. BindingExpression:Path=DataContext.Role; DataItem='MyItem_90931F6CDC904A032778416D7F3A5FB410232AF48F7B7245FOE8D783347E9ED5' (HashCode=34262603); target element is 'Button' (Name=''); target property is 'NoTarget' (type 'Object')
I think the problem is caused by the ambiguous use of DataContext, it recognize the internal DataContext of the ListView and not the external one, from the code behind.
Thanks for your attention and your help