Is there a way to add a DoubleClickEvent to each Row in xaml rather than using the event of the datagridcontrol?
Something like this (this code does not work):
<UserControl
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid" >
<xcdg:UserControl.Resources>
<Style TargetType="xcdg:DataRow">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<cmd:EventToCommand Command="{Binding SelectCommand, Mode=Default}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:DataGridControl}}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Style>
</xcdg:UserControl.Resources>
...
Use a template instead of a style. (This assumes that the xceed datagrid's DataRow is templatable.)
<UserControl ...>
<UserControl.Resources>
<ResourceDictionary>
<DataTemplate x:Key="DataTemplateKey">
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<cmd:EventToCommand Command="{Binding SelectCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<!-- put your row template here -->
</Grid>
<CheckBox Content="{Binding Path=ApplianceActionID, Converter={StaticResource LookupConverter}, ConverterParameter=ApplianceActionLookupValues}"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" />
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<!-- UI -->
</UserControl>
Related
How can we use the UWP's GridView to look like the following WPF DataGrid?
Remark: The data binding is not important. You can just assume a Pseudo-code (psedo class with attributes MyTableId, DateModified, Author).
WPF DataGrid XAML:
<Window x:Class="MyWPFProj.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...........
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="103*"/>
<ColumnDefinition Width="697*"/>
</Grid.ColumnDefinitions>
<DataGrid x:Name="dgMathDocs" IsReadOnly="True" AutoGenerateColumns="False" SelectionMode="Single" Margin="0,43,0,0" Grid.ColumnSpan="2">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Edit">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="btnEdit" Content="Edit" Click="btnEdit_Click"></Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Delete">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="btnDelete" Content="Delete" Click="btnDelete_Click"></Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="ID" Visibility="Collapsed" Binding="{Binding MyTableId}" />
<DataGridTemplateColumn Header="Date Modified">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding DateModified}" BorderThickness="0" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Author" Binding="{Binding Author}"/>
</DataGridHyperlinkColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
WPF DataGrid Display of the above XAML:
You could try to use DataGrid from Windows Community Toolkit.
More information you can find from Sample App on GitHub
I have a TreeView that is using a single HierarchicalDataTemplate. I know how to bind to a property of the parent TreeViewItem in a HierarchicalDataTemplate:
<Button
Command="{Binding DataContext.RemoveCommand,
RelativeSource={RelativeSource AncestorLevel=2,
AncestorType=TreeViewItem}}"
CommandParameter="{Binding ElementId}" />
However, this does of course not work for the top-most items, since there is no ancestor TreeViewItem - here, I want to use the DataContext of the TreeView itself. How can I bind the command to the TreeView's DataContext for the top-most elements of the tree view? If necessary, you can assume that the view model has a property of the same name as the hierarchical view models representing each tree item.
This is my modified MainWindow.xaml based on the SubModelCollection example of Elmish.WPF (repo on GitHub), that demonstrates how I thought I solved the problem. As I mentioned in the comment to the OP, I encountered a new problem with this solution, but I hope it can be ironed out without too much effort. I have a feeling it's a trivial problem that remains.
My intention here is that one HierarchicalDataTemplate will be used for the top level items, and another for all other items. To my surprise it looks like it actually works as far as manipulating the data correctly, and the buttons work on all levels, but WPF is not happy with what's going on. Nodes on level two collapses visually when I add, remove or move subnodes below them, and the Output pane in VS has something to tell:
"System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'TreeViewItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
"
I had the same kind of error before introducing SharedPart, so I don't think that's causing it.
This is MainWindow.xaml, the only file I modified.
<Window
x:Class="Elmish.WPF.Samples.SubModelCollection.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Single counter" Height="800" Width="1000"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<DataTemplate x:Key="SharedPart">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CounterId}" Width="250" Margin="10,5,10,5" />
<TextBlock Text="{Binding CounterValue, StringFormat='Counter value: {0}'}" Width="100" Margin="0,5,10,5" />
<Button Command="{Binding Decrement}" Content="-" Margin="0,5,10,5" Width="30" />
<Button Command="{Binding Increment}" Content="+" Margin="0,5,10,5" Width="30" />
<Button Command="{Binding Reset}" Content="Reset" Margin="0,5,10,5" Width="50" />
<TextBlock Text="{Binding StepSize, StringFormat='Step size: {0}'}" Margin="0,5,10,5" />
<Slider Value="{Binding StepSize}" TickFrequency="1" Maximum="10" Minimum="1" IsSnapToTickEnabled="True" Width="100" Margin="0,5,10,5" />
<Button Command="{Binding AddChild}" Content="Add child" Margin="0,5,10,5" />
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="Level2Data" ItemsSource="{Binding Path=ChildCounters}">
<StackPanel Orientation="Horizontal">
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource SharedPart}"/>
<Button
Command="{Binding DataContext.Remove, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=2}}"
CommandParameter="{Binding CounterId}"
Content="×" Margin="0,5,10,5" Width="20" />
<Button
Command="{Binding DataContext.MoveUp, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=2}}"
CommandParameter="{Binding CounterId}"
Content="↑" Margin="0,5,10,5" Width="20" />
<Button
Command="{Binding DataContext.MoveDown, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}, AncestorLevel=2}}"
CommandParameter="{Binding CounterId}"
Content="↓" Margin="0,5,10,5" Width="20"/>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="Level1Data" ItemsSource="{Binding Path=ChildCounters}" ItemTemplate="{StaticResource Level2Data}">
<StackPanel Orientation="Horizontal">
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource SharedPart}"/>
<Button
Command="{Binding DataContext.Remove, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}"
CommandParameter="{Binding CounterId}"
Content="×" Margin="0,5,10,5" Width="20" />
<Button
Command="{Binding DataContext.MoveUp, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}"
CommandParameter="{Binding CounterId}"
Content="↑" Margin="0,5,10,5" Width="20" />
<Button
Command="{Binding DataContext.MoveDown, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}"
CommandParameter="{Binding CounterId}"
Content="↓" Margin="0,5,10,5" Width="20"/>
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
<StackPanel Margin="0,20,0,10">
<Button Command="{Binding AddCounter}" Content="Add counter" Width="150" Margin="0,0,0,20" />
<TreeView ItemsSource="{Binding Counters}" ItemTemplate="{StaticResource Level1Data}">
</TreeView>
</StackPanel>
I'm porting over some Win RT code to UWP. One of the pages that doesn't work as expected is the HubPage.
I have a button in the HubSection HeaderTemplate which should be replacing the "see more" HyperLink. My button in my template appears but doesn't accept clicks.
The documentation states that I should be able to replace the "see more" hyperlink with my own template, I believe this is what my code is doing but doesn't work.
I'm unsure what value IsHeaderInteractive should be if I've attempting to replace the HubSection HeaderTemplate. Any help apprecaited
<Page
x:Class="Hub_Page.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Hub_Page"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<Style TargetType="HubSection">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Button Content="This doesn't click!"
Background="DarkCyan" Tapped="UIElement_OnTapped"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="outerGrid">
<Grid x:Name="innerGrid"
VerticalAlignment="Top">
<Hub x:Name="hub" SectionHeaderClick="Hub_OnSectionHeaderClick" >
<Hub.Header>
<!-- Back button and page title -->
<Grid>
<StackPanel Margin="13,0,20,0" Orientation="Horizontal">
<Button x:Name="backButton" Margin="0,0,20,0"/>
<TextBlock Text="x Manage Playlists" Margin="0,0,10,5" HorizontalAlignment="Left"/>
<Button Content="This does click"
Background="DarkGray" Tapped="UIElement_OnTapped"/>
</StackPanel>
</Grid>
</Hub.Header>
<!-- Playlists section -->
<HubSection Header="x Playlists" IsHeaderInteractive="True" >
<DataTemplate>
<ListView x:Name="playlistListView"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
SelectionMode="Single">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<!-- A playlist -->
<Grid HorizontalAlignment="Stretch">
<StackPanel Margin="10" Orientation="Vertical" HorizontalAlignment="Stretch" MaxWidth="500">
<TextBlock Text="{Binding Name}" TextTrimming="WordEllipsis" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</HubSection>
</Hub>
</Grid>
</Grid>
</Grid>
</Page>
It's by design. You could make your own HubSection's button by yourself. For example like the following:
<HubSection>
<DataTemplate>
<StackPanel>
<Button Content="Header" Click="Button_Click" Margin="0 0 0 10"></Button>
<TextBlock Text="here is content."></TextBlock>
</StackPanel>
</DataTemplate>
</HubSection>
After using MahApp Metro formy project in WPF I encountered a problem I can't solve. the framework works fine except when I am using the NumericUpDown control.
I can see this control onto my UserControl while I'am working on it. But at the compilation the code then becomes :
The tag 'NumericUpDown' does not exist in XML namespace "http://metro.mahapps.com/winfx/xaml/controls". Line 75 Position 26.
With my XAML code it could perhaps help :
<UserControl x:Class="FullTest.Tabs.DataGridStrategie" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:convertors="clr-namespace:FullTest.ModelView.Convertors"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:utils="clr-namespace:FullTest.UtilityClasses"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
<ObjectDataProvider MethodName="GetType"
ObjectType="{x:Type sys:Type}" x:Key="colorsTypeOdp">
<ObjectDataProvider.MethodParameters>
<sys:String>System.Windows.Media.Colors, PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</sys:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider ObjectInstance="{StaticResource colorsTypeOdp}" MethodName="GetProperties" x:Key="colorPropertiesOdp">
</ObjectDataProvider>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/emerald.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<DataGrid ItemsSource="{Binding Path=Str...}"
Grid.Row="0"
AutoGenerateColumns="False" Margin="0,0,-172,0" x:Name="MainGrid">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Colors ..." Width="Auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="superCombo" ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}" SelectedItem="{Binding BrushColor, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Width="20" Height="20" Margin="5" Background="{Binding Name}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Name of ..." x:Name="Str.." Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Name="itemNameTextBox" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Typ o....">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Name="TypeStrat" ItemsSource="{Binding Path=Typ....}" SelectedIndex="{Binding Index, UpdateSourceTrigger=PropertyChanged, Mode= TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!--Here Appears the problem due to the controller-->
<DataGridTemplateColumn Header="">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:NumericUpDown Grid.Row="0"
Grid.Column="1"
Height="23"
Margin="5,5,5,5"
Interval="1"
StringFormat="{}{0:###0}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I could provide more information if it can be useful.
I have a DataGrid and a custom ComboBox. The ComboBox used a ListBox to enable multi-select.
I intend to give a ObservableCollection<Data> Datas property as the data source for the ComboBox,where Data is a class with string name and bool checked. The problem is how to set up each column's visibility to a corresponding CheckBoxwhich used a Dataas its source ?
<Style x:Key="CheckBoxListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid x:Name="RootElement">
<CheckBox ClickMode="Press" Content="{Binding Path=Name}" IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Foreground="White"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I saw some post used something like the xmal below, but obviously I do not has any ElementName here.
<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
Visibility="{Binding IsChecked,
Converter={StaticResource visibilityConverter},
ElementName=chkShowPrice}"/>
This binding is not straight forward as it looks. Since DataGridTextColumn does not fall in the same visual tree as DataGrid, so it is not possible to bind the Visibility of the column directly. However, a bit tricky approach but you may use x:Reference for the same.
Here is how we can do it
XAML
<!--I added this element to provide the DataContext by using x:Reference-->
<FrameworkElement x:Name="contextProvider" />
<DataGrid Grid.Column="1"
AutoGenerateColumns="False"
ItemsSource="{Binding DD}"
x:Name="dg"
Style="{StaticResource DataGridDemoStyle}">
<DataGrid.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</DataGrid.Resources>
<i:Interaction.Behaviors>
<behavior:DataGridDropBehavior></behavior:DataGridDropBehavior>
</i:Interaction.Behaviors>
<DataGrid.Columns>
<DataGridTextColumn x:Name="Column3"
Binding="{Binding Symbol}"
Header="Symbol"
Width="*"
IsReadOnly="True"
Visibility="{Binding DataContext.Data[0].IsSelected, Source={x:Reference contextProvider}, Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn x:Name="Column4"
Binding="{Binding Ask}"
Header="Ask"
Width="*"
IsReadOnly="True"
Visibility="{Binding DataContext.Data[1].IsSelected, Source={x:Reference contextProvider}, Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn x:Name="Column5"
Binding="{Binding Bid}"
Header="Bid"
Width="*"
IsReadOnly="True"
Visibility="{Binding DataContext.Data[2].IsSelected, Source={x:Reference contextProvider}, Converter={StaticResource BooleanToVisibilityConverter}}" />
<DataGridTextColumn x:Name="Column6"
Binding="{Binding Volume}"
Header="Vol"
Width="*"
IsReadOnly="True"
Visibility="{Binding DataContext.Data[3].IsSelected, Source={x:Reference contextProvider}, Converter={StaticResource BooleanToVisibilityConverter}}" />
</DataGrid.Columns>
</DataGrid>
I have binded the items from the same Data bound to multi select combo box to the visibility of the columns
changed the following so that the DataContext is available to all the elements instead of just datagrid.
dg.DataContext = d;
to
DataContext = d;
lastly to enable the IsChecked binding modify the CheckBox from
<CheckBox ClickMode="Press" Content="{Binding Path=Name}" IsChecked="true" Foreground="White"/>
to
<CheckBox ClickMode="Press" Content="{Binding Path=Name}" IsChecked="{Binding IsSelected}" Foreground="White"/>
that's all you need for such binding.
here is the link to the provided sample project DataGridColumnsVisibilityBinding.zip
Let me know if this helps.