I have this DataGrid filled with products and there stocks and as well as an auto generated button per items, i want to call this auto generated button using there xNames so that when the stocks of a specific item became 0 i will simply disable it's button which is also auto generated, but my problem is i cannot call it.
I tried a lot such using FindNames in datagrid but still won't work\
<DataGrid.Columns>
<DataGridTextColumn IsReadOnly="True" Binding="{Binding id}" Header="Product ID" Width="Auto"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource ProductNameCellMargin}" IsReadOnly="True" Binding="{Binding item_name}" Header="Product Name" Width="*"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource ProductNameCellMargin}" IsReadOnly="True" Binding="{Binding item_price}" Header="Price" Width="*"></DataGridTextColumn>
<DataGridTextColumn ElementStyle="{StaticResource ProductNameCellMargin}" IsReadOnly="True" Binding="{Binding item_quantity}" Header="Quantity" Width="*"></DataGridTextColumn>
<DataGridTemplateColumn IsReadOnly="True" HeaderStyle="{StaticResource CenterGridHeaderStyle}" Header="Remove" MinWidth="50" CanUserSort="False" CanUserResize="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Background="Transparent" BorderBrush="Transparent" x:Name="select_item_btn" Padding="5, 2, 5, 2" Cursor="Hand" Click="remove_btn_Click">
<DockPanel>
<Image Height="18" Width="19" Source="img/Remove.png" />
</DockPanel>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
CodePudding user response:
You could use a DataTrigger
to disable the Button
based on the value of some source property, e.g.:
<Button Background="Transparent" BorderBrush="Transparent" x:Name="select_item_btn"
Padding="5, 2, 5, 2" Cursor="Hand" Click="remove_btn_Click">
<DockPanel>
<Image Height="18" Width="19" Source="img/Remove.png" />
</DockPanel>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding item_quantity}" Value="0">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
The above sample markup should disable the Button
when the item_quantity
property is 0
.
CodePudding user response:
Rather than handling click events it is usual in wpf to use a command with a button. Bind the command property of the button to an icommand in the parent datacontext / viewmodel or the item viewmodel.
ICommand has CanExecute.
If that returns false then the button will be disabled and not run.
https://learn.microsoft.com/en-us/answers/questions/433293/mvvm-relaycommand-icommand
The community toolkit mvvm makes defining commands pretty easy.
Here the last lambda expression is canexecute:
RemoveCommand = new RelayCommand(DoRemove, () => SelectedCustomer != null);
You would be checking stocks somehow instead of selectedcustomer, more like:
RemoveCommand = new RelayCommand(DoRemove, () => StockLevel > 0);
But, as the article illustrates, you can instead use an attribute
[RelayCommand(CanExecute = "HasStock")]
private void Remove()
I'm not sure what remove button does but you might want a command parameter for the row and the command in the parent viewmodel if you're removing a given row out the datagrid.
A RelayCommand is designed to receive a parameter to it's method.
A relativesource binding would allow you to bind from the button to the DataContext.RemoveCommand if necessary.