WPF Datagrid showing extra column - c#

My grid is showing an extra column.
Can someone help me please? I have two columns. Document name and document date. What is the third column that is showing up? The datasource has four properties. I need 2 of them.
Also, When the grid first loads how do I highlight the first row
<Grid VerticalAlignment="Stretch" Focusable="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500" ></ColumnDefinition>
<ColumnDefinition Width="6"></ColumnDefinition>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<GridSplitter Grid.Column="1" Grid.RowSpan="1" HorizontalAlignment="Center" VerticalAlignment="Stretch"
BorderBrush="DarkSlateGray" BorderThickness="1" Width="6" ShowsPreview="True" >
<GridSplitter.Background>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FF808385" Offset="0"/>
<GradientStop Color="#FFECF1F7" Offset="1"/>
</LinearGradientBrush>
</GridSplitter.Background>
</GridSplitter>
<ScrollViewer Name="scrollViewer" PreviewMouseWheel="ScrollViewer_OnPreviewMouseWheel">
<DataGrid Name = "dataGrid"
SelectionChanged="ShowDocument" AutoGenerateColumns="False"
PreviewMouseWheel="DataGrid_PreviewMouseWheel" >
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
<ItemsPresenter />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header = "Document Name" Binding = "{Binding Name, Mode=OneWay}" SortMemberPath="Name" />
<DataGridTextColumn Header = "Document Date" Binding = "{Binding DocumentDate, StringFormat=\{0:d\}, Mode=OneWay}" SortMemberPath="DocumentDate" />
</DataGrid.Columns>
</DataGrid>
</ScrollViewer>

Seems like you need to allow second column in your grid to use the remaining space like so:
<DataGridTextColumn Binding="{Binding DocumentDate, StringFormat=\{0:d\}, Mode=OneWay}"
Header="Document Date"
Width="*"
SortMemberPath="DocumentDate" />
See also: https://stackoverflow.com/a/5028932/7127128
Also you can select the first line by setting selected index in DataGrid:
<DataGrid Name = "dataGrid"
...
SelectedIndex="0"
...>

Related

WPF right align button in DataGrid Column Header

I'm looking at adding a filter button to the right hand side of my datagrid column header. I have succeeded in adding the button and have implemented all of the functionality I need I just can't seem to get the button to be right aligned in the header.
Here is my current XAML:
<DataGridTextColumn Width="2*" IsReadOnly="True" Binding="{Binding Load}" x:Name="temp">
<DataGridTextColumn.Header>
<Grid Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Load" />
<Button Grid.Column="1" x:Name="btnFilter" Content="+" Margin="3,0,0,0" Click="btnFilter_Click"></Button>
</Grid>
</DataGridTextColumn.Header>
</DataGridTextColumn>
This is how it looks currently and where I want the button to be positioned.
I thought using the grid would do the trick but when I select the grid and look at the designer it's width isn't the entire width of the column only the width for the textblock and button.
What am I missing in order to have the button right aligned in the header?
Use the HeaderStyle of the column to set the HorizontalContentAlignment property of the DataGridColumnHeader to Stretch:
<DataGridTextColumn ...>
<DataGridTextColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.Header>
<Grid Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="16"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Load" />
<Button Grid.Column="1" x:Name="btnFilter" Content="+" Margin="3,0,0,0" HorizontalAlignment="Right"></Button>
</Grid>
</DataGridTextColumn.Header>
</DataGridTextColumn>
While mm8's answer is perfectly correct, it would be (I believe) slightly more efficient to use a DockPanel, and it's certainly more consise:
<DataGridTextColumn ...>
<DataGridTextColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</DataGridTextColumn.HeaderStyle>
<DataGridTextColumn.Header>
<DockPanel>
<Button DockPanel.Dock="Right" x:Name="btnFilter" Content="+" Margin="3,0,0,0"></Button>
<TextBlock Text="Load" />
</DockPanel>
</DataGridTextColumn.Header>
</DataGridTextColumn>

binding datagrid column to selecteditem property

I have a datagrid where if a row is clicked upon the row details is shown. In the row details is another datagrid called dgRights.
So dgRights is bound to SelectItem.Funds where funds is a custom list. dgRights show 4 columns, 3 of which are bound fine however the fourth isn't (in my code below its called "Rights Sedol").
I want the column Rights Sedol to be bound to a property of the selectedItem not selectedItem.Funds, is this possible?
I've tried the lines of code below without luck,
<DataGridTextColumn Header="Rights Sedol" Binding="{Binding SelectedItem.NewSecurity.Sedol, RelativeSource={RelativeSource AncestorType=Window}}/>
2nd
<DataGridTextColumn Header="Rights Sedol" Binding="{Binding SelectedItem.NewSecurity.Sedol, RelativeSource={RelativeSource AncestorType=DataGrid}}/>
I also tried changing the ItemSource of the datagrid from SelectedItem.Funds to just SelectItem & changed the other 3 working columns to Funds.Code etc but this didn't display any data in the datagrid at all. So not sure what to do?
App.xaml - my row details data template
<DataTemplate x:Key="DG_RowDetailRGHTSHist">
<Grid x:Name="RowDetailGrid"
Margin="5"
HorizontalAlignment="Left">
<Border HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="250"
CornerRadius="5">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0"
Grid.Column="0"
Margin="5,5,5,5"
HorizontalAlignment="Left"
FontSize="12"
FontWeight="Bold"
Foreground="Black"
Text="Fund Summary">
</TextBlock>
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
ItemsSource="{Binding SelectedItem.Funds, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
RowStyle="{StaticResource DG_Row}"
ColumnHeaderStyle="{StaticResource DG_ColumnHeader}"
RowHeaderStyle="{StaticResource DG_RowHeaderNested}"
CellStyle="{StaticResource DG_Cell}"
Background="Silver"
HorizontalGridLinesBrush="LightGray"
VerticalGridLinesBrush="LightGray"
CanUserAddRows="False"
CanUserDeleteRows="False"
Margin="50,5,5,20"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Fund Code" Binding="{Binding Code}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Fund Code SS" Binding="{Binding CodeSS}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Rights Sedol" Binding="{Binding SelectedItem.NewSecurity.Sedol, RelativeSource={RelativeSource AncestorType=Window}}" IsReadOnly="True" MinWidth="75"/>
<DataGridTextColumn Header="Number of Rights" Binding="{Binding CurrentNominal, Mode=TwoWay, StringFormat={}{0:N0}}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Border>
</Grid>
</DataTemplate>
You want to access the 2nd datagrid up so you need to specify AncestorLevel=2.
{RelativeSource AncestorType=DataGrid, AncestorLevel=2}}

Templated sub-MenuItem not fitting in parent MenuItem's container

I'm struggling with the horizontal fitting of contents when trying to display a UserControl in a ContextMenu, by templating one of its MenuItem:
<ControlTemplate x:Key="MyUserControlMenuItemTemplate" TargetType="{x:Type MenuItem}">
<Grid>
<MyUserControl/>
</Grid>
</ControlTemplate>
<MenuItem x:Key="MyUserControlMenuItem" x:Shared="False" Header="My user control">
<MenuItem Template="{StaticResource MyUserControlMenuItemTemplate}"/>
</MenuItem>
<ContextMenu x:Key="MyUserControlContextMenu" x:Shared="False">
<ContextMenu.ItemsSource>
<CompositeCollection>
<StaticResource ResourceKey="MyUserControlMenuItem"/>
<!-- More stuff here -->
</CompositeCollection>
</ContextMenu.ItemsSource>
</ContextMenu>
This is mostly working, and I'm getting the context menu displayed under the desired circumstances and the UserControl accessible within it, as intended (a different question is whether this is a good design decision). The UserControl is just arranging some controls in a Grid.
The problem is that, depending on the position of the containing window and the actual screen resolution, sometimes the panel containing the templated menu item is not wide enough to hold it completely, and the user control is cut.
How could I get the UserControl to be dynamically resized in order to fit within the horizontal space available in the containing panel?
The UserControl XAML markup is as follows:
<UserControl x:Class="MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Grid.Row="0"
Height="210"
ItemsSource="{Binding ...}"
SelectedItem="{Binding ...}"
SelectionMode="Single">
<ListView.View>
<GridView ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<GridViewColumn DisplayMemberBinding="{Binding ...}" Header="First Name" Width="Auto"/>
<GridViewColumn DisplayMemberBinding="{Binding ...}" Header="Last Name" Width="Auto"/>
<GridViewColumn DisplayMemberBinding="{Binding ...}" Header="Address" Width="Auto"/>
</GridView>
</ListView.View>
</ListView>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Margin" Value="4"/>
<Setter Property="Height" Value="24"/>
<Setter Property="Width" Value="24"/>
</Style>
<Style x:Key="ImageStyle" TargetType="{x:Type Image}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.35"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Button x:Name="FirstPageButton" Grid.Column="0" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
<Button x:Name="PreviousPageButton" Grid.Column="1" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
<Button x:Name="NextPageButton" Grid.Column="2" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
<Button x:Name="LastPageButton" Grid.Column="3" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
<Button x:Name="OpenButton" Grid.Column="5" Style="{StaticResource ButtonStyle}">
<Image Source="..." Style="{StaticResource ImageStyle}"/>
</Button>
</Grid>
</Grid>
</UserControl>
I don't really think the issue is in the UserControl, though, but I may be well wrong.

Multi column list in windows 8 phone

I am trying to create a app to display tabular list (ID, Name, Lname) in the windows 8 phone.
My XAML file is as below
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style x:Key="ListBoxStyle" TargetType="ListBoxItem">
<Setter Property="Background" Value="{StaticResource PhoneSemitransparentBrush}" />
<Setter Property="Margin" Value="3,5" />
<Setter Property="FontSize" Value="20" />
<Setter Property="BorderBrush" Value="{StaticResource PhoneBorderBrush}" />
<!-- Replace the default item template with a basic template that does not highlight selected items. -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SummaryStyle" TargetType="TextBlock">
<Setter Property="Margin" Value="5" />
<Setter Property="Width" Value="75" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
</Grid.Resources>
<StackPanel Orientation="Horizontal">
<TextBlock Text="ID" Width="100" />
<TextBlock Text="Name" Width="150"/>
<TextBlock Text="LName" Width="150"/>
</StackPanel>
<ScrollViewer Margin="-5,13,3,36" Height="558">
<ListBox Name="lstBox"
ItemsSource="{Binding}"
Height="380" HorizontalAlignment="Left" Margin="5,25,0,0"
VerticalAlignment="Top" Width="444" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ID}" />
<TextBlock Text="{Binding FName}" />
<TextBlock Text="{Binding LName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Grid>
and I call the below code on the button click even
List<Customers> cust = new List<Customers>();
cust.Add(new Customers(1, "Ganesh", "S"));
cust.Add(new Customers(2, "Shan", "S"));
cust.Add(new Customers(3, "Anjan", "A"));
lstBox.ItemsSource = cust;
But, it does not display the list it is just showing the column. These customer name should display as in windows 8 phone
ID Name LName
1 Ganesh S
2 Shan S
3 Anjan A
What is missing in the code? or What should I follow while to display multi column list in windows 8 phone?
You have defined three columns but the StackPanel is placed in the first column (default behavior), hence i guess that you are not able to view the data.
Or probably you can assign the header TextBlocks to the grid (remove the stackpanel) and within the itemtemplate define another grid with similar width which should help you achieve the layout.
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBlock Text="ID" Width="100" Grid.Column="0"/>
<TextBlock Text="Name" Width="150" Grid.Column="1"/>
<TextBlock Text="LName" Width="150" Grid.Column="2"/>
and then your template like
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding ID}" Grid.Column="0"/>
<TextBlock Text="{Binding FName}" Grid.Column="1"/>
<TextBlock Text="{Binding LName}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
(not tested code just re arranged as per your post) hope this helps
Create a Grid inside the StackPanel. In that create a column.
Here it looks like:
<ScrollViewer Margin="-5,13,3,36" Height="558">
<ListBox Name="lstBox"
ItemsSource="{Binding}"
Height="380" HorizontalAlignment="Left" Margin="5,25,0,0"
VerticalAlignment="Top" Width="444" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Specify width" />
<ColumnDefinition Width="Specify width" />
<ColumnDefinition Width="Specify width" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding ID}" Grid.Column="0" />
<TextBlock Text="{Binding FName}" Grid.Column="1" />
<TextBlock Text="{Binding LName}" Grid.Column="2" />
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>

How to use wpf expender alignment

I am trying to create a WPF window to have a simple expander to extend the datagrid when the user clicks on the More expander button. When the user wants to hide the datagrid, user just has to clik on the Less expander button.
I am also using dock panel to separate header, left, right and footer.
The problems are :
I want to have the less button to be in center before the user
click on the more expander button. When the user clicks on the more
expander button, the less button will be pushed to the left, to show
the datagrid on the right.
How do I change the name of the expander when its closed and
open. Can I do it at the xaml level?
Below is the xaml code:
<Window x:Class="M.SalesWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SalesWindow" Height="300" Width="300">
<DockPanel>
<StackPanel DockPanel.Dock="Top">
<Label FontSize="28" Content="Sales">
</Label>
</StackPanel>
<StackPanel DockPanel.Dock="Left" Width="auto" HorizontalAlignment="Center">
<Label FontSize="15" Content="Enter Amount" Height="26" Width="168" />
<Separator Width="168" />
</StackPanel>
<StackPanel DockPanel.Dock="Right">
<Expander ExpandDirection="Left" HorizontalAlignment="Right" VerticalAlignment="Stretch">
<Expander.Header>
<TextBlock Text="More">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Expander.Header>
<Expander.Content>
<StackPanel>
<DataGrid ItemsSource="{Binding Products}">
</DataGrid>
</StackPanel>
</Expander.Content>
</Expander>
</StackPanel>
</DockPanel>
</Window>
Thank you.
Replace your code with the below code and see the magic. This will also solve your problem of alignment as per your requirement. I have removed the DockPanel as you can achieve the similar result with this piece of code.
<StackPanel>
<StackPanel>
<Label FontSize="28" Content="Sales">
</Label>
</StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" HorizontalAlignment="Center">
<Label FontSize="15" Content="Enter Amount" Height="26" Width="168" />
<Separator Width="168" />
</StackPanel>
<Expander Grid.Column="1" ExpandDirection="Left" HorizontalAlignment="Right" VerticalAlignment="Stretch">
<Expander.Style>
<Style TargetType="Expander">
<Setter Property="IsExpanded" Value="False" />
<Setter Property="Header">
<Setter.Value>
<TextBlock Text="Less">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsExpanded,RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Header">
<Setter.Value>
<TextBlock Text="More">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
<Expander.Content>
<StackPanel>
<DataGrid ItemsSource="{Binding Products}">
</DataGrid>
</StackPanel>
</Expander.Content>
</Expander>
</Grid>
</StackPanel>
The trick lies under the following lines of code.
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

Categories

Resources