Update Grid Row Cell Image when a user selects image from dialog - c#

I have an Image and a button side by side in a DevExpress grid, when the user clicks the button I would like the user to be able to select from a FileDialog a new image that should immediately show in the Image Field. When the user updates the rest of the fields in the row the IPropertyChange event should fire and store the row. How can I achieve this in WPF?
XAML:
<dxg:GridColumn FieldName="Image" Header="Image" >
<dxg:GridColumn.CellTemplate>
<DataTemplate>
<DockPanel>
<Image Source="{Binding RowData.Row.Image, Converter={StaticResource BinaryImageConverter}}" Width="100" />
<Button x:Name="BrowseFilePath" Height="20" Width="20" Content="..." Visibility="Hidden" CommandParameter="{Binding RowData.Row}" />
<!--<Button x:Name="BrowseFilePath" Height="20" Width="20" Content="..." Visibility="Hidden" Command="{Binding Source={x:Static local:FacilitiesBrowseImagePathDialog.BrowsePathCommand}}" CommandParameter="{Binding RowData.Row}" />-->
</DockPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dxg:GridRow}}" Value="True">
<Setter TargetName="BrowseFilePath" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</dxg:GridColumn.CellTemplate>
</dxg:GridColumn>

Related

WPF combo box header

I need to show only the Icon in the combo box if the combo box is clicked the icon and the text needs to be shown. As I am not familiar with how to achieve this.
Please help me in achieving this.
<ComboBox Name="cmbColors">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This will show the rectangle and text in the combo box and the drop down of the combo box. But my requirement is only to show the color filled rectangle in the combo box.
I am not sure whether I understand what you are trying to do, but my best guess is that you want to hide the text block if some other control has focus. If so, you can do something like this:
<ComboBox>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
<TextBlock x:Name="text" Text="{Binding Name}" />
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="False">
<Setter TargetName="text" Property="Visibility" Value="Collapsed" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
If you are instead trying to say that you want a different template for the header than for the dropdown, then you could do something like described in one of the answers to this question.
<ComboBox>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
<TextBlock x:Name="text" Text="{Binding Name}" />
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ComboBoxItem}}}" Value="{x:Null}">
<Setter TargetName="text" Property="Visibility" Value="Collapsed" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

How to select listview item when clicking button

Inside my listview I´ve created a control template. Inside this template I made a button, so that every item inside mit listview has a button. This button represents an link which opens the directory that is shown. When I click the button, my program opens the explorer as I expect it. But when I click the button of an item that is not selected it opens the path of the selected item. So my question is, how can I change the selected item when I click the button inside my listview.
Here is how it looks like:
As you can see "R1" is selected, but I click on the link of "R3". What happens is, that C:\Temp\Folder1 gets opened, because "R1" is still the selecteditem. What I wish to is that C:\Temp\Folder3 gets opend. I think the trick should be that "R3" gets selected when clicking the button that represents the link. Does anyone know how to that?
This is my XAML-Code:
<ListView Grid.Row="1" ItemsSource="{Binding MyCollection}" FontSize="20" SelectedItem="{Binding SelectedMember, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="7,10,7,0" x:Name="ListView1" SelectionChanged="ListView1_SelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn Header="Header 1" Width="150"/>
<GridViewColumn Header="Header 2" Width="120"/>
<GridViewColumn Header="Header 3" Width="120"/>
<GridViewColumn Header="Header 4" Width="560"/>
<GridViewColumn Header="Header 5" Width="100"/>
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="560"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" Content="{Binding ID}" HorizontalAlignment="Center"/>
<ContentPresenter Grid.Column="1" Content="{Binding Name}" HorizontalAlignment="Center"/>
<ContentPresenter Grid.Column="2" Content="{Binding Description}" HorizontalAlignment="Center"/>
<Button Grid.Column="3" Content="{Binding Path}" Style="{StaticResource Link}" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.GoToPathCommand }" HorizontalAlignment="Left" Margin="5,0,0,0" IsEnabled="{Binding ButtonEnabled}"/>
<ContentPresenter Grid.Column="4" Content="{Binding Owner}" HorizontalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.GoToPathCommand }"
This Command will jump to the Cmd of the ViewModel. I assume that the Command will check which item is selected and it will access it's property Path.
Avoiding this behavior, You can create a Command that will take a parameter and set it from Binding:
<Button Content="{Binding Path}"
Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}, Path=DataContext.GoToPathCommand }"
CommandParameter="{Binding Path}"/>
Now the command itself must be adjusted:
public MyCmd : ICommand
{
public void Execute(object parameter)
{
string path = (string) parameter;
//Open the path via explorer
}
}
Try adding below trigger too in the ListViewItem Style
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>

Dynamically generated buttons seem to not fire their commands?

I have a ListBox which is dynamically filled during runtime. It has a DataType of RequirementPreview which is needed to bind certain properties to triggers, sources and parameters. There is, however, 1 command-binding that needs to trigger a command that is set in the datacontext but has nothing to do with the template datatype.
What I want is that the Button fires the 'RevertDelete'-command and sends the Guid of the RequirementPreview to which the button belongs. As of now, nothing happens when I press the button.
Xaml:
<ListBox Grid.Row="1" Grid.ColumnSpan="3" Margin="5" IsEnabled="{Binding IsEnabled}" ItemsSource="{Binding Requirements}" SelectionMode="Extended">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding SelectionChanged}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDeleted}" Value="True">
<Setter Property="Foreground" Value="red"/>
</DataTrigger>
</Style.Triggers>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type myModels:RequirementPreview}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="45"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Name}" ToolTip="{Binding Name}" HorizontalAlignment="Stretch"/>
<Button Grid.Column="2" HorizontalAlignment="Right" IsEnabled="{Binding IsEnabled}" Visibility="{Binding IsDeleted, Converter={StaticResource BoolToVisibility}}"
Command="{Binding RevertDelete}" CommandParameter="{Binding Guid}" Height="10" Width="10"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Xaml.cs:
[Dependency]
public IMainViewModel ViewModel
{
get { return this.DataContext as IMainViewModel; }
set { this.DataContext = value; }
}
Edit:
Tried messing around with the databinding;
Command="{Binding RelativeSource={x:Static RelativeSource.PreviousData}, Path=RevertDelete}"
Command="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=RevertDelete}"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=RevertDelete}
Neither made a difference.
I guess RevertDelete command is not a part of RequirementPreview type which works as a data context for the template. You'll need to use relative source binding for this command:
<Button Command="{Binding DataContext.RevertDelete, RelativeSource={RelativeSource AncestorType=ListBox}}"
CommandParameter="{Binding Guid}" />

Ability to click on a button as part of a background style WPF

I have a ListBox that sometimes contains no items. If this ListBox contains no items, then a watermark and a notification in the form of a button with a tool tip will be displayed. I originally had the button at the bottom right corner of my screen. But it was requested I move the button to a more central location, specifically just below the watermark in the ListBox. I moved the button to the background of the ListBox initially but that did not work because I was unable to get the tool tip or press the button. My question is: Is there a way to have the button function properly on the background of the ListBox.
Style:
<VisualBrush x:Key="WatermarkStyle" Stretch="None" AlignmentX="Center" AlignmentY="Center">
<VisualBrush.Visual>
<Grid>
<Button
Margin="0,50,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Command="{Binding ReloadCommand}"
ToolTip="{Binding Path=NotificationTip}"
Visibility="{Binding Path=ShowNotification,
Converter={StaticResource TrueToVisibleConverter}}"
Style="{StaticResource StaticStyle}"
IsEnabled="{Binding Path=CanReload}">
<Image Source="{Binding Path=NotificationIcon}" Stretch="Uniform" Width="35"/>
</Button>
<TextBlock FontFamily="SEGOEWP" FontSize="22" FontWeight="Normal" HorizontalAlignment="Center"
VerticalAlignment="Center" Foreground="Gray" Opacity="1" Text="{Binding BackgroundWatermark}"/>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
ListBox:
<ListBox x:Name="ListBox"
Grid.Row="2"
Grid.ColumnSpan="3"
BorderThickness="1"
ItemsSource="{Binding Path=ListView}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SelectedItem="{Binding SelectedDevice}"
SelectionMode="Single">
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource Self}}" Value="False">
<Setter Property="Background" Value="{StaticResource WatermarkStyle}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.Style>

Set Parent Property From Children in WPF

I've created a status bar:
<StatusBar>
<StatusBarItem >
<WrapPanel>
<Image Source="/MyApp;component/Images/icon.png" />
<TextBlock Name="_StatusbarUser" Text="Username" />
</WrapPanel>
</StatusBarItem>
</StatusBar>
How to create a trigger, when i set the textblock visibility to collapse,
it will also triger parent status bar visibility.
I've try using style bellow, but didn't work
<StatusBar Grid.Row="2" Name="_Statusbar">
<StatusBar.Resources>
<Style TargetType="{x:Type StatusBarItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type TextBlock}}, Path=Visibility}" Value="Collapsed">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StatusBar.Resources>
<StatusBarItem>
<WrapPanel>
<Image Source="/MyApp;component/Images/icon.png" />
<TextBlock Name="_StatusbarUser" Text="Username" />
</WrapPanel>
</StatusBarItem>
</StatusBar>
Help please, thx
Better bind parent property to child property:
<StatusBar>
<StatusBarItem Visibility="{Binding ElementName=_StatusbarUser, Path=Visibility}">
<WrapPanel>
<Image Source="/MyApp;component/Images/icon.png" />
<TextBlock Name="_StatusbarUser" Text="Username" />
</WrapPanel>
</StatusBarItem>
</StatusBar>

Categories

Resources