WPF change text property on TextBlock in ControlTemplate - c#

I have TabControl and I have a plan to generate dynamicaly TabItems and fill up with ControlTemplate.
ControlTemplate:
<Window.Resources>
<ControlTemplate x:Key="Qtemp" TargetType="Control">
<ControlTemplate.Resources>
<ControlTemplate x:Key="yesButton" TargetType="{x:Type Button}">
<Grid>
<Image Visibility="Visible" Name="Normal" Source="/TabItemTemplate;component/Images/yes.png" />
<Image Visibility="Hidden" Name="Pressed" Source="/TabItemTemplate;component/Images/yes_p.png" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsPressed" Value="True">
<Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>
<Setter TargetName="Pressed" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="noButton" TargetType="{x:Type Button}">
<Grid>
<Image Visibility="Visible" Name="Normal" Source="/TabItemTemplate;component/Images/no.png" />
<Image Visibility="Hidden" Name="Pressed" Source="/TabItemTemplate;component/Images/no_p.png" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Normal" Property="Visibility" Value="Hidden"/>
<Setter TargetName="Pressed" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="circleButton">
<Grid>
<Ellipse>
<Ellipse.Fill>
<ImageBrush ImageSource="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" />
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>
</ControlTemplate.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Ellipse Grid.Row="1" Margin="-1024,-75,0,0" Name="progress_bar" Fill="#FF01325E" Width="424" Height="424" StrokeThickness="0" RenderTransformOrigin=".5,.5">
<Ellipse.Clip>
<RectangleGeometry Rect="0,0,212,424"/>
</Ellipse.Clip>
<Ellipse.RenderTransform>
<RotateTransform Angle="45"/>
</Ellipse.RenderTransform>
</Ellipse>
<Grid Grid.RowSpan="3" Grid.Row="0" Width="Auto" Height="Auto" >
<Grid.Background>
<ImageBrush ImageSource="/TabItemTemplate;component/Images/Q_bg.png" />
</Grid.Background>
</Grid>
<TextBlock Grid.Row="1" Name="QBody" Width="400" Margin="-120,-100,0,0" Foreground="#FF333333" TextWrapping="Wrap" FontFamily="Arial" FontSize="28" TextAlignment="Left" FontWeight="Bold" VerticalAlignment="Center" Text="{Binding}" />
<StackPanel Grid.Row="1" Width="350" HorizontalAlignment="Right">
<Button Width="172" Height="172" Name="BT_yes" Template="{StaticResource yesButton}" Click="BT_NextQ" />
<Button Width="172" Height="172" Name="BT_no" Margin="0,20,0,0" Template="{StaticResource noButton}" Click="BT_NextQ" />
</StackPanel>
<Image Grid.Row="2" Source="/TabItemTemplate;component/Images/toolbar.png" />
<Button Grid.Row="2" Width="56" Height="56" Tag="/TabItemTemplate;component/Images/home.png" HorizontalAlignment="Left" Margin="90,0,0,15" Template="{StaticResource circleButton}" />
<Button Grid.Row="2" Width="56" Height="56" Tag="/TabItemTemplate;component/Images/back.png" HorizontalAlignment="Left" Margin="26,0,0,15" Template="{StaticResource circleButton}" />
</Grid>
</ControlTemplate>
</Window.Resources>
In XAML:
<TabControl HorizontalAlignment="Stretch" Name="navTab" VerticalAlignment="Stretch" BorderThickness="0" Padding="0">
<TabItem Name="tabItem1a" Header="static">
<Control Template="{StaticResource Qtemp}" />
</TabItem>
</TabControl>
CS file:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
for (int i = 1; i < 6; i++)
{
TabItem newTab = new TabItem();
Control newControl = new Control();
newControl.Template = (ControlTemplate)FindResource("Qtemp");
//TextBlock tb = (TextBlock)newControl.Template.FindName("Qbody", newControl);
//tb.Text = "TEST" + i.ToString();
newTab.Header = "Dynamic"+i.ToString();
newTab.Name = "Question" + i.ToString();
newTab.Content = newControl;
navTab.Items.Add(newTab);
}
}
In template I have TextBlock "Qbody" and Ellipse "progress_bar".
Im trying add text to "Qbody" and RorateTransform Angle for "progress_bar" but I cant get access to any controls in template.
I tried:
TextBlock tb = (TextBlock)newControl.Template.FindName("Qbody", newControl);
But it returns null.
Can anyone help me with it.
I dont know what im doing wrong.
Is any other way to set these two controls.

you have this marked as mvvm, but what you are doing violates mvvm principles. Your progress bar and textbox should be bound to your viewmodel, then you can access thier properties there.
Your controls are null because they have not been created yet.
But if you want to use code behind you need to access the controls in the apply template event of the framework element (Tab Control)
Framework ApplyTemplate Event
Cheers
EDIT 1:
You have to implement iNotifyPropertyChanged for the UI to be made "aware" of changes to the properties in the viewmodel. You would raise this event for every iteration of your property counter.
Also, the scope of what you need cannot be covered in one answer. I recommend reading more about MVVM and WPF and maybe use an existing framework to help like MVVM-Light or Caliburn.Micro.

Related

Dynamic property of a text box within a button using a button template

I have a few buttons to set up in C# WPF, and I like to use a button template.
I can set the template and then use it in my grid, but how do I change the text of the TextBox per button and also other properties like the color of the rectangle?
Here is my template:
<Window.Resources>
<ControlTemplate x:Key="menuButton_Type1" TargetType="Button">
<Grid >
<Rectangle x:Name="Normal" Fill="#FFFDC776" HorizontalAlignment="Left" Height="25" Width="82" RadiusX="7" RadiusY="7"/>
<Rectangle x:Name="Pressed" Fill="White" HorizontalAlignment="Left" Height="25" Width="82" RadiusX="7" RadiusY="7" Visibility="Hidden"/>
<Rectangle x:Name="Disable" Fill="#FF707070" HorizontalAlignment="Left" Height="25" Width="82" RadiusX="7" RadiusY="7" Visibility="Hidden"/>
<Border Width="82" Height="25" Padding="0,0,5,0">
<TextBlock Text="EXIT" FontFamily="{StaticResource Swiss911}" FontSize="18" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Normal" Property="Visibility" Value="Hidden" />
<Setter TargetName="Pressed" Property="Visibility" Value="Visible" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Normal" Property="Visibility" Value="Hidden" />
<Setter TargetName="Disable" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
I use the template button in my XAML grid like this:
<Grid>
<Button Template="{StaticResource menuButton_Type1}" Margin="18,226,-18,-226" />
</Grid>
I would like to change the text of the TextBlock currently set to "EXIT" and also the color of one of the Rectangle, in this case the normal one. How do I do this?
I tried to use dynamic properties, but that did not work for me.
I found your answer on these pages:
What is the template binding vs binding?
TemplateBinding Markup Extension
You can simply put the binding to the Text property of TextBlock on your ControlTemplate.
You should add the Content property of the button to TextBlock's text property:
<TextBlock Text="{TemplateBinding Content}" FontFamily="{StaticResource Swiss911}" FontSize="18" HorizontalAlignment="Right" VerticalAlignment="Bottom" />
Then you can set the content property of Button, the Content property of Button will be passing to the your TextBlock's Text property.
<Button Template="{StaticResource menuButton_Type1}" Content="Exit" Margin="100" />
I tested with these Buttons:
<Button Template="{StaticResource menuButton_Type1}" Content="Exit" Margin="0,0,0,0" />
<Button Template="{StaticResource menuButton_Type1}" Content="Close" Margin="100,0,0,0" />
<Button Template="{StaticResource menuButton_Type1}" Content="Open" Margin="200,0,0,0" />

Propagate ListBoxItem IsSelected trigger to child control

I'm developing a CheckedListBox with self removable ListBoxItems. The problem is that an item only gets checked if the user clicks on the CheckBox area, which is kind of awkward.
How do I create ListBoxItem triggers (IsSelected) to check the checkboxes on a "DataSourced" ListBox? Eg:
Below is my control (all other code have been omitted for brevity):
<ListBox x:Name="executors" ItemsSource="{Binding Executors}" HorizontalAlignment="Left" Height="121" Margin="23,19,0,0" VerticalAlignment="Top" Width="362">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Height" Value="30" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="30" />
</Grid.ColumnDefinitions>
<CheckBox Margin="4,8" IsChecked="{Binding Enabled}">
<ContentPresenter Content="{Binding Description}">
</ContentPresenter>
</CheckBox>
<Button Command="{Binding DataContext.RemoveExecutorCommand, ElementName=executors}" CommandParameter="{Binding}" Background="White" Height="22" Width="22" Grid.Column="1">
<Image Source="trash.png" Stretch="Fill" Width="14" Height="14" />
</Button>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Executors is a ObservableCollection of Executor which has Enabled and Description as members.
For further reference for those who come across this same question, here's a working snippet I have done. I couldn't find any working sample anywhere, so this might be of much use.
The main idea here was to either propagate the selection event to the CheckBoxes, which sounds too much of a work, or to simple extend the CheckBox selection area to fit the ListBoxItem.
Below is a sample on how to achieve the second option:
<ListBox x:Name="executors" ItemsSource="{Binding Executors}" HorizontalAlignment="Left" Height="121" Margin="23,19,0,0" VerticalAlignment="Top" Width="362" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Height" Value="30"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<CheckBox Content="{Binding Description}" IsChecked="{Binding Enabled}" VerticalContentAlignment="Center" Margin="4,0"/>
<Button Command="{Binding DataContext.RemoveExecutorCommand, ElementName=executors}" CommandParameter="{Binding}" Width="21" Height="21" Background="White" Grid.Column="1">
<Image Source="trash.png" Stretch="Fill" Width="14" Height="14" />
</Button>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
This should produce the following:

SizeToContent issue with custom windowstyle when start

My problem is: I have two sizes of window which changes according to CheckBox. Below have a screenshot of the problem:
Like you can see, my app starts with incorrect size but when I change the checkbox everything works fine, the window size become normal
I already tested to set CheckBox when app starts by code behind and not work.
Here's my XAML of custom windowstyle
<Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
GlassFrameThickness="-1"
ResizeBorderThickness="5"
CaptionHeight="36"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="#FF2D2D30" />
<Setter Property="Background" Value="#FF2D2D30" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="BorderThickness" Value="15,35,15,15"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Window}">
<Grid>
<Border
x:Name="MainBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
</Border>
<DockPanel
x:Name="MainDock"
VerticalAlignment="Top"
LastChildFill="False">
<TextBlock
VerticalAlignment="Bottom"
DockPanel.Dock="Left"
Margin="20 0 0 0"
FontSize="14"
Foreground="#ff999999"
Text="{TemplateBinding Title}" />
<Button x:Name="btnClose"
Width="15"
Margin="5"
Click="CloseClick"
Content="X"
DockPanel.Dock="Right"
Background="Transparent"
BorderBrush="Transparent"
Foreground="White"
VerticalContentAlignment="Center"
WindowChrome.IsHitTestVisibleInChrome="True"
/>
<Button
x:Name="btnRestore"
Width="15"
Margin="5"
Click="MaximizeRestoreClick"
Content="#"
DockPanel.Dock="Right"
Background="Transparent"
BorderBrush="Transparent"
Foreground="White"
VerticalContentAlignment="Center"
WindowChrome.IsHitTestVisibleInChrome="True"/>
<Button
x:Name="btnMinimize"
Width="15"
Margin="5"
Click="MinimizeClick"
Content="_"
DockPanel.Dock="Right"
Background="Transparent"
BorderBrush="Transparent"
Foreground="White"
VerticalContentAlignment="Center"
WindowChrome.IsHitTestVisibleInChrome="True" />
</DockPanel>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsFullScreen}" Value="True">
<Setter Property="Visibility" Value="Collapsed" TargetName="MainDock"/>
<Setter Property="BorderThickness" Value="0 0 0 0"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
XAML code of window
<Window x:Class="STEP_QuickSound_UI.Window_SelectConnection"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="QuickSoundX"
Closing="Window_Closing"
Topmost="true"
Background="{StaticResource WindowBackground}"
Style="{StaticResource CustomWindowStyle}"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterScreen">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition/>
<RowDefinition Height="0.2*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Label Margin="5" Foreground="White">Tipo de conexão</Label>
<StackPanel Orientation="Horizontal">
<RadioButton Margin="5" Foreground="White" IsChecked="True" Name="RemoteConnection" GroupName="Connection">Remota</RadioButton>
<RadioButton Margin="5" Foreground="White" Name="LocalConnection" GroupName="Connection">Local</RadioButton>
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="1" >
<Label Foreground="White" Margin="5">IP Address</Label>
<TextBox Name="IpAddress" Margin="5">192.168.0.5</TextBox>
<Label Foreground="White" Margin="5">Porta</Label>
<TextBox Name="Port" Margin="5">8281</TextBox>
<StackPanel.Style>
<Style TargetType="StackPanel">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=RemoteConnection, Path=IsChecked}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
<StackPanel Grid.Row="2" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Margin="5" Grid.Column="0" Style="{StaticResource Button}" Click="SaveClick">Salvar</Button>
<Button Margin="5" Grid.Column="1" Style="{StaticResource Button}" Click="CancelClick">Cancelar</Button>
</Grid>
</StackPanel>
</Grid>
ADDEND:
If I remove the custom window style, works fine, so it's something i'm missing there.
You can get rid of this behaviour by removing SizeToContent="WidthAndHeight" from your XAML and setting the SizeToContent programmatically once the window has been loaded:
public partial class Window_SelectConnection : Window
{
public Window_SelectConnection()
{
InitializeComponent();
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
SizeToContent = SizeToContent.WidthAndHeight;
Loaded -= OnLoaded;
}
}
You may want to create a custom window class that does this for you:
public class CustomWindow : Window
{
public CustomWindow()
{
Loaded += CustomWindow_Loaded;
}
private void CustomWindow_Loaded(object sender, RoutedEventArgs e)
{
SizeToContent = SizeToContent.WidthAndHeight;
Loaded -= CustomWindow_Loaded;
}
}
...and inherit from this one:
public partial class Window_SelectConnection : CustomWindow
<local:CustomWindow x:Class="STEP_QuickSound_UI.Window_SelectConnection" ...

WPF MenuItem apply style to boxed header

I'm currently trying to apply styling to my menuItem. I had to center it's header inside the control, and the only way to it that I had found is this:
<MenuItem>
<MenuItem.Header>
<TextBlock Text="About" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</MenuItem.Header>
</MenuItem>
Now, I am trying to apply styles, but I can't seem to manage to bind the textboxes' text from style to the actual xaml value.
My style:
<Style x:Key="MenuItemBaseStyle" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#0a99f3" />
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid Background="{TemplateBinding Background}">
<MenuItem>
<MenuItem.Header>
<TextBlock Text="{TemplateBinding Text}" />
</MenuItem.Header>
</MenuItem>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TemplateBinding is just one of the approaches I tried, though none worked even remotely close.
EDIT - FULL XAML ON REQUEST:
<Window x:Class="DownloadManager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DownloadManager"
xmlns:controls="clr-namespace:DesignInControl"
mc:Ignorable="d"
Title="MainWindow" Height="700" Width="1000" Background="#22282a" ResizeMode="NoResize">
<Border BorderThickness="1" BorderBrush="#ffcd22" Margin="10,10,10,10">
<Grid>
<controls:CircularProgressBar VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,10,10" SegmentColor="#ffcd22" StrokeThickness="5" Percentage="100" Radius="80" Grid.ZIndex="0"/>
<Border VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,10,10" Width="170" Height="170">
<TextBlock FontSize="60" Text="10%" FontFamily="simplifica" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<Image x:Name="noshare_png" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="-8,10" Source="noshare.png" Width="100" Height="100"/>
<Border Width="210" Height="100" Margin="97,10,665,540">
<TextBlock Text="NoShare" FontSize="85" FontFamily="simplifica" Foreground="#ffcd22" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<Menu x:Name="menu" HorizontalAlignment="Left" Height="100" Margin="352,10,0,0" VerticalAlignment="Top" Width="600" FontFamily="simplifica" FontSize="30">
<MenuItem Height="100" Width="200" Style="{StaticResource MenuItemBaseStyle}">
<MenuItem.Header>
<TextBlock Text="File"/>
</MenuItem.Header>
</MenuItem>
<MenuItem Height="100" Width="200" Style="{StaticResource MenuItemBaseStyle}">
<MenuItem.Header>
<TextBlock Text="Settings"/>
</MenuItem.Header>
</MenuItem>
<MenuItem Height="100" Width="200" Style="{StaticResource MenuItemBaseStyle}">
<MenuItem.Header>
<TextBlock Text="About"/>
</MenuItem.Header>
</MenuItem>
</Menu>
</Grid>
</Border>
</Window>
Use MenuItem.HeaderTemplate.
<Style x:Key="MenuItemBaseStyle" TargetType="MenuItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#0a99f3" />
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
Updated: Combined your style with the original solution.

Border is added only to the first text block in WPF

Edit : I realized what the problem is, when I add the border, The second TextBlock sits on top of the first TextBlock. Still have to figure out why this is happening.
Original question:
I have a number of TextBlocks in my xaml. I want to add a border around some textblocks. I tried the following methods.
Method 1:
<Style x:Key="BorderForTextBlock" TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Black" />
</Style>
<TextBlock1../>
<Border Style="{StaticResource BorderForTextBlock}">
<TextBlock2.../>
</Border>
Method 2:
<TextBlock1../> //This is where the border is added.
<Border BorderThickness="1" BorderBrush="Black">
<TextBlock2 ..../> //This is where I want to add the border
</Border>
A border is added only to the first TextBlock in the xaml no matter to which TextBlock I add the border. I don't want the border on the first TextBlock. I have no clue why this is happening.
This is my xaml :
<Grid Background="LightYellow" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" ></ColumnDefinition>
<ColumnDefinition Width="3.5*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28*" ></RowDefinition>
<RowDefinition Height="120*" ></RowDefinition>
<RowDefinition Height="28*"></RowDefinition>
<RowDefinition Height="74*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Margin="10,0,5,0" FontWeight="SemiBold" Text="{x:Static res:Resources.source1"/>
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock x:Name="txtBlock1" FormatTest:FormattedTextBehavior.FormattedText="{Binding Path= content1}" Margin="0,0,0,0" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap"/>
</Border>
<TextBlock Grid.Row="1" Margin="10,0,5,0" FontWeight="SemiBold" Text="{x:Static res:Resources.source2}"/>
<RichTextBox Background="LightYellow" Margin="0,0,0,0" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True" Grid.Row="1" Grid.Column="1" IsReadOnly="True" >
<FlowDocument>
<Paragraph>
<Run Text="{Binding content2, Mode=TwoWay}"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
<TextBlock Grid.Row="2" Margin="10,0,5,0" FontWeight="SemiBold" Text="{x:Static res:Resources.source3"/>
<TextBlock Text="{Binding content3, Mode=TwoWay}" Margin="0,0,0,0" Grid.Row="2" Grid.Column="1" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True" TextWrapping="Wrap"/>
<TextBlock Grid.Row="3" Margin="10,0,5,0" FontWeight="SemiBold" Text="{x:Static res:Resources.source4}"/>
<TextBox Text="{Binding content4, Mode=TwoWay}" Margin="0,0,0,0" Grid.Row="3" Grid.Column="1" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True" TextAlignment="Left" TextWrapping="Wrap" Background="LightYellow" IsReadOnly="True"/>
</Grid>
instead of
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock x:Name="txtBlock1" FormatTest:FormattedTextBehavior.FormattedText="{Binding Path= content1}" Margin="0,0,0,0" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap"/>
</Border>
Have
<Border Grid.Row="0" Grid.Column="1" BorderBrush="Black" BorderThickness="1">
<TextBlock x:Name="txtBlock1" FormatTest:FormattedTextBehavior.FormattedText="{Binding Path= content1}" Margin="0,0,0,0" TextWrapping="Wrap"/>
</Border>
This should solve the issue with placement of text blocks
This is how it looks at my end
Try this and let us know
You can use style with trigger and put the style either in windows resources or app resources depending upon scope you want
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.Resources>
<Style x:Key="NotCalledBorder" TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="Height" Value="20"/>
<Setter Property="Width" Value="30"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="TextDecorations" Value="Underline" />
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Style="{StaticResource NotCalledBorder}" Grid.Row="0">
<TextBlock Text="test1" Grid.Row="0" OpacityMask="Black">
</TextBlock>
</Border>
<TextBlock Text="test2" Grid.Row="1"></TextBlock>
<Border Style="{StaticResource NotCalledBorder}" Grid.Row="2">
<TextBlock Text="test3" Grid.Row="2" OpacityMask="Black"></TextBlock>
</Border>
<TextBlock Text="test4" Grid.Row="3"></TextBlock>
</Grid>
</Window>
Conditional style in WPF. Adding border to two textblocks only. You can apply style and add to as many as you want

Categories