How can I make AvalonEdit unfocusable and uneditable in my WPF App?
I've tried this:
<avalonEdit:TextEditor
x:Name="AvalonQuery"
xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit"
FontFamily="Consolas"
SyntaxHighlighting="SQL"
ShowLineNumbers="True"
IsReadOnly="True"
Focusable="False"/>
IsReadOnly="True" works, but I don't know why Focusable="False" simply doesn't work.
<avalonEdit:TextEditor.Resources>
<Style TargetType="{x:Type avalonEdit:TextArea}">
<Setter Property="Focusable" Value="False"/>
</Style>
</avalonEdit:TextEditor.Resources>
You can see here: https://github.com/icsharpcode/AvalonEdit/blob/master/ICSharpCode.AvalonEdit/TextEditor.xaml
Related
I want to have image as background in my richtextbox command.
I'm using, but I can only set background value to already defined colors, not images. (I were using scrollbarviewer but it doesnt show in my richtextbox)
<RichTextBox x:Name="richTextBox" HorizontalAlignment="Left" Height="285" VerticalAlignment="Top" Width="880" VerticalScrollBarVisibility="Visible" IsReadOnly="True" Foreground="#FFA02626" Background="{x:Null}">
<RichTextBox.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="Red"/>
</Style>
</RichTextBox.Resources>
</RichTextBox>
The Value can be any object, so it can be an ImageBrush. You can do it with the element syntax.
<RichTextBox x:Name="richTextBox" HorizontalAlignment="Left" Height="285" VerticalAlignment="Top" Width="880" VerticalScrollBarVisibility="Visible" IsReadOnly="True" Foreground="#FFA02626" Background="{x:Null}">
<RichTextBox.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="cool-northern-lights-pic-4.jpg"/>
</Setter.Value>
</Setter>
</Style>
</RichTextBox.Resources>
</RichTextBox>
Try like this-
<RichTextBox>
<RichTextBox.Background>
<ImageBrush ImageSource="some.jpg"/>
</RichTextBox.Background>
</RichTextBox>
See if this helps.
I need some help in trying to recreate the following style:
The sea of red can be ignored because it's just the background the textbox is sitting on.
To create the textbox I use the following xaml:
<TextBox Name="tbSorageName"
Grid.Column="1"
Width="250"
Height="30"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
IsReadOnly="True"
Style="{StaticResource MainTextBoxStyle}"
Text="{Binding SelectedStorage.Name,
Mode=OneWay,
UpdateSourceTrigger=PropertyChanged}" />
To style it, I used the following style:
<Style x:Key="MainTextBoxStyle" TargetType="TextBox">
<Setter Property="FontSize" Value="16" />
<Setter Property="Foreground" Value="Snow" />
<Setter Property="FontFamily" Value="Calibri" />
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Background" Value="{DynamicResource MainTextBox_BGBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource MainTextBox_BorderBrush}" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="TextAlignment" Value="Left" />
</Style>
The Brushes I use are:
<SolidColorBrush x:Key="MainTextBox_BGBrush" Color="#3A3A3A" />
<SolidColorBrush x:Key="MainTextBox_BorderBrush" Color="#656565" />
That creates the basic textbox I use in my application, but I want to take my design much further by floating some meaningful text that describes the contents of textbox on the right hand side of the text box - So it should be anchored to the right hand side.
You can do this easily via 2 approaches.
1.Create a user control that consists of a textbox and a textblock. The Xaml for the UserControl would look similar to the following
<Grid Width="{Binding Path=Width, ElementName=tbSorageName}" Height="{Binding Path=Height, ElementName=tbSorageName}">
<TextBox Name="tbSorageName"
Grid.Column="1"
Width="250"
Height="30"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
IsReadOnly="True"
Style="{StaticResource MainTextBoxStyle}"
Text="hello" />
<TextBlock HorizontalAlignment="Right" Margin="5" Foreground="Red" FontStyle="Italic">Name</TextBlock>
</Grid>
2.Overlay an Adorner on the textbox and draw the description over the Textbox yourself via an OnRender Override.
I would go with the Usercontrol approach since that is cleaner and easier to maintain.
Well, actually rotated -90 degrees from horizontal is what I mean.
I need to do this because the text for the header is quite long but the cell value is short, and I want to fit a lot of columns on the screen.
Is it possible to do this easily or do I need to learn about resources and templates first? I don't mind a "hack" solution!
This will rotate the whole ColumnHeaderCell:
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="270" />
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
Be aware: this means HorizontalContentAlignment is then a VerticalContentAlignment and vice versa.
Here is another way to do it:
<Style x:Key="soDataGrid_ColumnHeaderRotateStyle" TargetType="DataGridColumnHeader" >
<Setter Property="ContentTemplate" >
<Setter.Value>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding}"
FontWeight="Bold" Width="60"
VerticalAlignment="Center" TextAlignment="Center"
HorizontalAlignment="Center">
<TextBlock.LayoutTransform>
<RotateTransform Angle="270" />
</TextBlock.LayoutTransform>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
You can use the style as follows
<DataGridComboBoxColumn Header="Portrait /
Landscape" Width="42"
HeaderStyle="{StaticResource soDataGrid_ColumnHeaderRotateStyle}"
SelectedItemBinding="{Binding Orientation}"
ItemsSource="{Binding Mode=OneWay,
Source={StaticResource languageEnum}}" />
I find this approach gives you a lot of control. It is helpful to use the line break code in long header text.
Unfortunately I have found you need to hardcode the width of the rotated textblock - maybe there is a better way to set this width based on the text content.
Let's say I have a UserControl with 4 Borders:
<Border />
<Border />
<Border />
<Border />
Now in my Resources I can go:
<Style TargetType="{x:Type Border}">
... change some properties here
</Style>
Now this is all good, but it will target all borders in my UserControl.
But what if I just want to target a subset of them?
I'd like to go:
<Border Class="Type1" />
<Border Class="Type1" />
<Border />
<Border />
And then go:
<Style TargetType="{x:Type Border}" TargetClass="Type1">
... change some properties here
</Style>
But this obviously doesn't exist, is there some other way I can achieve what I'm after?
Thanks
Though the syntax isn't quite as clean as in CSS, it is a lot more specific.
To build on your example, what you're looking for is:
<Border Style="{StaticResource Type1}" />
<Border Style="{StaticResource Type1}" />
<Border />
<Border />
And then go:
<Style TargetType="{x:Type Border}" x:Key="Type1">
... change some properties here
</Style>
Remember that WPF styles don't actually cascade like CSS does.
A more detailed styling reference:
https://web.archive.org/web/20141210000517/http://dotnetslackers.com/articles/wpf/StylesResourcesAndControlTemplatesInWPF.aspx
Something that I find most people are not aware of is WPF's ability to nest Styles within Style.Resources. For example:
<!-- Define a new style for Borders called InfoBox, that will have a red background,
and further override all buttons within it to have Yellow Text. An extra style,
"Strawberry" is also defined, that lets specific buttons be selected to be styled
as Green FG on DarkRed BG -->
<Style TargetType="{x:Type Border}" x:Key="InfoBox">
<Setter Property="Background" Value="Red"/>
<Style.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="DarkYellow"/>
</Style>
<Style TargetType="{x:Type Button}" x:Key="Strawberry">
<Setter Property="Foreground" Value="Green"/>
<Setter Property="Background" Value="DarkRed"/>
</Style>
</Style.Resources>
</Style>
...
<Border Style="{DynamicResource InfoBox}">
<StackPanel>
<Button Content="I am a banana!"/>
<Button Style="{DynamicResource Strawberry}" Content="I am red!"/>
</StackPanel>
</Border>
While not exactly the same as CSS (There isn't much support for standard pseudo-selectors), this gives you a huge amount of power and flexibility. Couple this with skillful use of ItemsControls and you can do some great things.
you can set the style directly on the <Border> using an x:key and the StaticResource (or DynamicResource) property of the Border. if you would like to change the style at runtime, then you should lean towards using the DynamicResource over the StaticResource.
<Style x:Key="something" TargetType="{x:Type Border}">
</Style>
<Border style="{StaticResource something}"/>
<Style x:Key="styleKey" TargetType="{x:Type Border}">
... change some properties here
</Style>
and
<Border Style="{StaticResource styleKey}"
This is hopefully going to be a really simple answer, I'm just not seeing the proverbial wood for the trees I think.
I've got a DataGridCell style in which I want to bind the content of the cell to the source property of an image, here's the XAML I'm using at the moment:
<Style x:Key="DataGridImageCellStyle" TargetType="{x:Type toolkit:DataGridCell}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type toolkit:DataGridCell}">
<Border Background="Transparent"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0"
SnapsToDevicePixels="True">
<Image Source="{Binding RelativeSource={RelativeSource AncestorType=toolkit:DataGridCell}, Path=Content}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Note that at the moment i'm binding the Image Source to Content.. which doesnt work, i've also tried Value, which didn't work!
So my question is, nice and simply.. what is the correct binding to use to get the cell's content into the source property of this image?
Thanks in advance!
Pete
If the column is a DataGridTextColumn then you might be able to bind to the Text property of the TextBlock that is its content:
<Image Source="{Binding RelativeSource=
{RelativeSource AncestorType=DataGridCell}, Path=Content.Text}" />
That's really a hack, though. If you want to display an image in a column, you should probably use a DataGridTemplateColumn:
<DataGridTemplateColumn Header="...">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding SomeProperty}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Where SomeProperty is the property of your row object that has the image path.