Dynamically set Textblock size when Column containing it, is resized - c#

I have an xceed grid (not sure if that is important) and one of the columns has a CellContentTemplate that has a TextBlock. Instead of the textblock width being automatically set to the size of the text, I want it to be the size of the column. I allow resizing, so this complicates things a bit. Is there a way to dynamically change the TextBlock width when the column gets resized, in code behind?
EDIT: CellContentTemplate
<DataTemplate x:Key="CellTemplate.TaskName">
<StackPanel Orientation="Horizontal">
<TextBlock Tag="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
<TextBlock Text="{Binding Path=Name}" >
<ui:DragDropBinding.DragSource>
<Binding Mode="TwoWay" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type XceedProviders:DataGridControlWithSelectedItems}}" Path="BindableSelectedItems" PresentationTraceSources.TraceLevel="High"/>
</ui:DragDropBinding.DragSource>
</TextBlock>
</TextBlock>
</StackPanel>
</DataTemplate>

Hi this is because you enclosing TextBlock in StackPanel . One simple workaround is instead of two TextBlock use two Run to bind two properties like
<DataGridTemplateColumn Header="Name" Width="*" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Background="Green">
<Run Text="{Binding Name}"/>
<Run Text="{Binding Rollno}"/>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Now textblock will expand with the width of column .I hope this will help.

Related

Microsoft Toolkit DataGrid not refresh data in view

I have datagrid to show some data in xaml of UWP application.I use MVVM and a i have view model for the view. Items source of datagrid is observable collection. I have problem with refresh data on xaml view. If i us DataGridTextColumn as column data, data refreshed properly on view, but if i use DataGridTemplateColumn data on view not refresh.
This code work properly:
<mtc:DataGrid Name="ArticlesListView"
ItemsSource="{x:Bind ViewModel.Articles, Mode=OneWay}"
AutoGenerateColumns="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
SelectionMode="Single"
RowDetailsVisibilityMode="Collapsed"
IsReadOnly="True">
<mtc:DataGrid.Columns>
<mtc:DataGridTextColumn Header="Barcode" Binding="{Binding Barcode}"/>
<mtc:DataGridTextColumn Header="Name" Binding="{Binding Description}"/>
</mtc:DataGrid.Columns>
</mtc:DataGrid>
I clear and fill observable collection with new data and data on view is refresh properly.
This code not work properly:
<mtc:DataGrid Name="ArticlesListView"
ItemsSource="{x:Bind ViewModel.Articles, Mode=OneWay}"
AutoGenerateColumns="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
SelectionMode="Single"
RowDetailsVisibilityMode="Collapsed"
IsReadOnly="True">
<mtc:DataGrid.Columns>
<mtc:DataGridTemplateColumn Header="Barcode">
<mtc:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:DataGridCell Background="{Binding Active, Converter={StaticResource BoolToColorConverter}, ConverterParameter=true}"
Data="{Binding Barcode}"/>
</DataTemplate>
</mtc:DataGridTemplateColumn.CellTemplate>
</mtc:DataGridTemplateColumn>
<mtc:DataGridTemplateColumn Header="Name">
<mtc:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:DataGridCell Background="{Binding Active, Converter={StaticResource BoolToColorConverter}, ConverterParameter=true}"
Data="{Binding Description}"/>
</DataTemplate>
</mtc:DataGridTemplateColumn.CellTemplate>
</mtc:DataGridTemplateColumn>
</mtc:DataGrid.Columns>
</mtc:DataGrid>
I clear and fill observable collection with new data but on view stays old data.
Can anyone help me with this issue?
Thank you for help. I figured out the problem. The problem is that property change event does not reach the custom control that i made for DataTemplate and changes does not apply in it. I change this lines of code:
<mtc:DataGridTemplateColumn Header="Barcode" Tag="Barcode">
<mtc:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:DataGridCell Background="{Binding Active, Converter={StaticResource BoolToColorConverter}, ConverterParameter=true}"
Data="{Binding Barcode}"/>
</DataTemplate>
</mtc:DataGridTemplateColumn.CellTemplate>
</mtc:DataGridTemplateColumn>
to this:
<mtc:DataGridTemplateColumn Header="Barcode" Tag="Barcode">
<mtc:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid Background="{Binding Active, Converter={StaticResource BoolToColorConverter}, ConverterParameter=true}">
<TextBlock Text="{Binding Barcode, Converter={StaticResource ObjectToStringConverter}}"
Style="{StaticResource DataGridCellContentStyle}"/>
</Grid>
</DataTemplate>
</mtc:DataGridTemplateColumn.CellTemplate>
</mtc:DataGridTemplateColumn>
and everything works fine. Its just have to define DataTemplate in datagrid not use external user control for DataTemplate because changes does not reach user control and does not apply to the view.

TemplateColumn doesn't diplay the Header in DataGrid

I made in my DataGrid a TemplateColumn with this structure:
<DataGridTemplateColumn Header="Squadra" Width="SizeToCells" IsReadOnly="True" HeaderStringFormat="Squadra">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image MaxHeight="20" MaxWidth="20" Source="{Binding Path= 'crestUrl' , Converter={StaticResource NameToImageConverter}}" />
<TextBlock Text="{Binding name}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
But the Header "Squadra" insn't visible when I start my solution, also if I populate the DataGrid through code the Header became visible. Is this a bug of WPF or I do something wrong?
I think it 's because your column is visible but with a width of 0 (SizeToCells and no content).
Set a MinWidth="150"

Listbox selection change not firing on click on child in list box item

I have a wpf user control which contains a Listbox which is binded to my View Model. Each Listbox item is consists of three textblock. I made the UI in a way that when user clicks on the Frist TextBlock(Title) function in my View Model will get called.
To uniquely Identify the ListBox item corresponding to which text block now got clicked. I added another property in my view model which is bindied to SelectionChanged Event in the Listbox. So whenever my TextBlock binded command get exectuted I will use my SelectionChanged Property to find which List Box Item and use its data context.
But the issue I am facing now is that when User clicks on the First textblock, selectionchanged event is not firing. When User clicks outside the First Textblock only Selection Changed event is getting fired. Which made my view model to process wrong list box items.
Following is the XAML snippet.
<ListBox ScrollViewer.CanContentScroll="False" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedItem="{Binding SelectedNotificationItem}" ItemsSource="{Binding MyArray}" BorderThickness="0" Margin="0, 0, 0, 0" ItemContainerStyle="{StaticResource HoverBackgroundStyle}" Name="NotificationListBox" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderThickness="4,0,0,0" BorderBrush="{Binding ColorThing, Converter={StaticResource SeverityToColorConverter} }" Margin="0, 0, 0, 0">
<StackPanel Margin="8, 0" Orientation="Vertical">
<TextBlock Style="{StaticResource HoverUnderlineStyle}" FontWeight="Bold" TextTrimming="CharacterEllipsis" Name="Title" Text="{Binding Title}" TextWrapping="WrapWithOverflow" Margin="0,4,0,0" >
<TextBlock.InputBindings>
<MouseBinding MouseAction="LeftClick" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.ClickTitleCommand}"></MouseBinding>
</TextBlock.InputBindings>
</TextBlock>
<TextBlock FontWeight="Normal" Name="Desc" Text="{Binding Description}" TextWrapping="WrapWithOverflow">
</TextBlock>
<TextBlock FontWeight="Normal" Foreground="Gray" Name="Date" Text="{Binding CreationTime, StringFormat={}{0:ddd MM.dd.yyyy} }" Margin="0,4,0,4">
</TextBlock>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Could you try changing your XAML to SelectedItem="{Binding SelectedNotificationItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Change the ListBox into an ItemsControl and change the orientation to horizontal

DataGrid Repeated Column

I'm creating a WPF View with a DataGrid.
The DataGrid is bound to the field Properties on the ViewModel.
However, for one of the columns I want each row to have the same value bound to some other property on the View model.
Specificically, the table is showing named monetary values and the repeated column will show a currency code (which is the same for each row).
I can't figure out how to do this, I've tried to use the following:
<DataGrid ItemsSource="{Binding Properties}">
<DataGrid.Columns>
<DataGridTextColumn Header="Target" Binding="{Binding Target}"/>
<DataGridTextColumn Header="Value" Binding="{Binding Value}"/>
<DataGridTemplateColumn Header="Currency">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Properties.NodeCurrency}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
I'm using the Caliburn framework with no typed DataContext in the View. I'm not sure if this matters to the question though.
You can try to do it via RelativeSource of Binding. For example:
<TextBlock Text="{Binding Property.NodeCurrency, RelativeSource={RelativeSource AncestorType=Window}}"/>
You can use RelativeSource/FindAncestor on your binding to bind to an other DataContext than the current one :
<TextBlock
Text="{Binding Property.NodeCurrency, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
With assistance from both answerers the actual binding I needed was:
<TextBlock Text="{Binding DataContext.Property.NodeCurrency, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
The missing bit was specifying that I'm binding to the DataContext of the UserControl and then delving down into the properties on the ViewModel.

Silverlight DataGrid validation show validation error for all objects|properties

I have a ObservableCollection<T> where T: INotifyDataErrorInfo.
Objects in this collection have validation errors, then I bind this collection to Silverlight 4 DataGrid, is there a way to show this validation error in DataGrid? (show red cell for invalid properties for each object). By default DataGrid show validation error only when I begin to edit row, and only for active row.
I haven't succeeded with a TextBlock control, so I used a disabled TextBox
You can change the template of the TextBox, I mean to remove border and to set its background really transparent.
<sdk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Items}" IsReadOnly="False" SelectionMode="Single">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="Title" Binding="{Binding Title}"/>
<sdk:DataGridTemplateColumn Header="Link" Width="100">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Link, Mode=TwoWay}" Margin="2"
IsEnabled="False" BorderThickness="0" Background="Transparent"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding Link, Mode=TwoWay}" Margin="2"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>

Categories

Resources