I have a WPF RichTextBox and i'm trying to do is change the style:
FontFamily, FontSize, FontWeight, Color and some more.
I can change some of this values on the selected Text,
but i can't find a TextDecorationProperty
CodeExample:
TextSelection textRange = richTextBoxWpf.Selection;
if (btBold.IsChecked ?? false)
{
textRange.ApplyPropertyValue(FontWeightProperty, FontWeights.Bold);
btBold.IsChecked = true;
}
else
{
btBold.IsChecked = false;
textRange.ApplyPropertyValue(FontWeightProperty, FontWeights.Normal);
}
My code fails on set the Property:
var pens = new System.Windows.Media.Pen(System.Windows.Media.Brushes.Black, 1);
textRange.ApplyPropertyValue(TextDecoration.PenProperty, pens);
Fail Error-Message: "Die Pen-Eigenschaft ist für die Textformatierung nicht gültig."
Sorry, after a long search I found the Solution myself:
It in the Documents.Inline class:
TextSelection textRange = richTextBoxWpf.Selection;
textRange.ApplyPropertyValue(Inline.TextDecorationsProperty, TextDecorations.Underline);
Related
In Xamarin.Forms using a glyph from a Fontello font is simple:
Download a font e.g. smiley.ttf.
Add to project as Embedded Resource
Export the font:
[assembly: ExportFont("smiley.ttf", Alias = "smiley")]
Use the glyph in xaml for the Text property:
<StackLayout BackgroundColor="#eeeeee">
<!--Uses glyph #E800 from smiley.ttf-->
<Button BorderColor="Aqua"
BackgroundColor="Yellow"
BorderWidth="5"
CornerRadius="10"
FontSize="150"
FontFamily="smiley"
Text=""
TextColor="Black"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
HeightRequest="200"
WidthRequest="200" />
</StackLayout>
And presto:
I would like to do the same thing in Winforms. Here's what I tried:
public MainForm()
{
InitializeComponent();
// For the sake of simplicity, the TTF is copied to output directory...
var path = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Fonts", "smiley.ttf");
// ... and loaded here.
privateFontCollection.AddFontFile(path);
var fontFamily = privateFontCollection.Families[0];
Debug.Assert(fontFamily.Name == "smiley", "Expecting 'smiley' is the font family name");
button1.Font = new Font(fontFamily, 12F);
button1.UseCompatibleTextRendering = true;
// Shows 'A'
// button1.Text = "A";
// Shows nothing.
button1.Text = "\u0E00";
}
PrivateFontCollection privateFontCollection = new PrivateFontCollection();
Is such a thing even possible? I tried various settings of button1.UseCompatibleTextRendering = true and Application.SetCompatibleTextRenderingDefault(true) without success.
The answer to the question: Can Fontello glyph be used for Winforms button in a similar way as for a Xamarin Forms button? is YES.
Thanks to Jimi for the comment pointing out my typo, and also for mentioning the necessity of disposal which I was also not aware of.
Here is the working code:
public partial class MainForm : Form
{
// https://stackoverflow.com/a/36509042/5438626
// https://learn.microsoft.com/en-us/dotnet/desktop/winforms/advanced/how-to-create-a-private-font-collection?view=netframeworkdesktop-4.8
public MainForm()
{
InitializeComponent();
// For the sake of simplicity, the TTF is copied to output directory...
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Fonts", "smiley.ttf");
// ... and loaded here.
privateFontCollection.AddFontFile(path);
var fontFamily = privateFontCollection.Families[0];
Debug.Assert(fontFamily.Name == "smiley", "Expecting 'smiley' is the font family name");
button1.Font = new Font(fontFamily, 12F);
button1.UseCompatibleTextRendering = true;
button1.Text = "\uE800";
button1.BackColor = Color.Yellow;
}
PrivateFontCollection privateFontCollection = new PrivateFontCollection();
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
privateFontCollection.Dispose();
}
base.Dispose(disposing);
}
}
How can I edit specific line in RichTextBox from code?
I add lines to RichTextBox
FlowDocument mcFlowDoc = new FlowDocument();
Paragraph para = new Paragraph();
para.Inlines.Add(new Run("I am a RichTextBox control line 1\n"));
para.Inlines.Add(new Run("I am a RichTextBox control line 2\n"));
para.Inlines.Add(new Run("I am a RichTextBox control line 3\n")
{
Foreground = Brushes.Red
});
mcFlowDoc.Blocks.Add(para);
RichTextBox1.Document = mcFlowDoc;
my XAML
<RichTextBox Margin="5" Name="RichTextBox1" FontSize="16" VerticalAlignment="Top"
Width="500" Height="220">
</RichTextBox>
Now I want to add a button while clicking on it (click event) the second line will change to "I finally got to do it"
Replace a line like this:
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
string lineToReplace = "I am a RichTextBox control line 2";
string newLine = "I finally got to do it";
TextRange text = new TextRange(RichTextBox1.Document.ContentStart, RichTextBox1.Document.ContentEnd);
TextPointer current = text.Start.GetInsertionPosition(LogicalDirection.Forward);
while (current != null)
{
string textInRun = current.GetTextInRun(LogicalDirection.Forward);
if (!string.IsNullOrWhiteSpace(textInRun))
{
int index = textInRun.IndexOf(lineToReplace);
if (index != -1)
{
TextPointer selectionStart = current.GetPositionAtOffset(index, LogicalDirection.Forward);
TextPointer selectionEnd = selectionStart.GetPositionAtOffset(lineToReplace.Length, LogicalDirection.Forward);
TextRange selection = new TextRange(selectionStart, selectionEnd);
selection.Text = newLine;
selection.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
RichTextBox1.Selection.Select(selection.Start, selection.End);
RichTextBox1.Focus();
}
}
current = current.GetNextContextPosition(LogicalDirection.Forward);
}
}
If your text structure is always the same you can simply find required Run and change it in click handler like this:
var par = (Paragraph) RichTextBox1.Document.Blocks.FirstOrDefault();
var run = (Run) par.Inlines.Skip(1).First();
run.Text = "I finally got to do it\n";
Quick and dirty:
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
TextRange textRange = new TextRange(
// TextPointer to the start of content in the RichTextBox.
RichTextBox1.Document.ContentStart,
// TextPointer to the end of content in the RichTextBox.
RichTextBox1.Document.ContentEnd
);
// get the lines of text
string[] lines =textRange.Text.Split(new[] { Environment.NewLine } , StringSplitOptions.RemoveEmptyEntries);
// get the second line
lines[1] = "I finally got to do it" + Environment.NewLine;
// build a string from the string array
StringBuilder builder = new StringBuilder();
foreach (string value in lines)
{
builder.Append(value);
}
// test the text in the RichTextbox
Paragraph para = new Paragraph();
para.Inlines.Add(new Run(builder.ToString()));
RichTextBox1.Document.Blocks.Clear();
RichTextBox1.Document.Blocks.Add(para);
}
and add line breaks properly to your document:
FlowDocument mcFlowDoc = new FlowDocument();
Paragraph para = new Paragraph();
para.Inlines.Add(new Run("I am a RichTextBox control line 1"));
para.Inlines.Add(Environment.NewLine);
para.Inlines.Add(new Run("I am a RichTextBox control line 2"));
para.Inlines.Add(Environment.NewLine);
para.Inlines.Add(new Run("I am a RichTextBox control line 3")
{
Foreground = Brushes.Red
});
mcFlowDoc.Blocks.Add(para);
RichTextBox1.Document = mcFlowDoc;
I'm trying change the line thickness in a serie dinamically created, I need turn the line more thick.
Below, follow the code to bind the created serie on chart component. It works fine, but I tryed adapt this in this code and I had no sucess.
Please help, thanks.
Style style = new Style(typeof(LineDataPoint));
style.Setters.Add(new Setter(LineDataPoint.OpacityProperty, (double)(0.0)));
style.Setters.Add(new Setter(LineDataPoint.BackgroundProperty, dadosSerie.ColorSerie));
LineSeries lineSerie = new LineSeries()
{
Title = dadosSerie.SerieTitle,
IndependentValueBinding = new Binding("Key"),
DependentValueBinding = new Binding("Value"),
DependentRangeAxis = dadosSerie.EixoY,
DataPointStyle = style,
ItemsSource = dadosSerie.DataSerie,
};
chtGraficos.Series.Add(lineSerie);
Have you tried adding a Style for the serie's Polyline instead?
It seams the style for the LineDataPoint is actually for every point on the serie.
Here is a working sample of a chart fully created on code-behind. You just have to create a window named MainWindow and add a reference on the project to System.Windows.Controls.DataVisualization.Toolkit:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var valueList = new Dictionary<string, int>();
valueList.Add("Developer", 60);
valueList.Add("Misc", 20);
valueList.Add("Project Manager", 40);
var style = new Style(typeof(Polyline));
style.Setters.Add(new Setter(Polyline.StrokeThicknessProperty, 10d));
var series = new LineSeries
{
PolylineStyle = style,
ItemsSource = valueList,
DependentValuePath = "Value",
IndependentValuePath = "Key",
};
var lineChart = new Chart { Height = 254 };
lineChart.Series.Add(series);
var mainGrid = new Grid();
mainGrid.Children.Add(lineChart);
this.Content = mainGrid;
}
}
I found function to print content of Wpf grid but the print is cropped.
Can anybody know why?
the function:
private void PrintTest()
{
FlowDocument document;
Window window;
CreateWindowToPrint(out document, out window);
PrintDialog printDialog = new PrintDialog();
window.Show();
IDocumentPaginatorSource dps = document;
if (printDialog.ShowDialog() == true)
{
printDialog.PrintDocument(dps.DocumentPaginator, "test");
}
}
and:
private void CreateWindowToPrint(out FlowDocument document, out
Window window)
{
document = new FlowDocument { };
var test = new PrintedTest() { DataContext = this.DataContext };
document.Blocks.Add(new BlockUIContainer { Child = test });
window = new Window {Content = document, Visibility = System.Windows.Visibility.Hidden };
}
The UserControl PrintedTest contains my grid.
I don't really have much experience with printing in WPF but I thought I would give it a try.
I could reproduce your problem, and I could not solve it so far.
But In my research I have found an alternative, which is more simple to print the Grid:
var printDialog = new PrintDialog();
var result = printDialog.ShowDialog();
if (result.HasValue && result.Value)
{
var testControl = new PrintedTest() { DataContext = this.DataContext };
printDialog.PrintVisual(testControl, "My WPF printing a DataGrid");
}
Instead of sending the PrintTest you could actually just send directly the grid.
I am attempting to highlight text in a databound ListBox and highlight matching strings exactly like the email application on Windows Phone 7.
The search button pulls up a Popup, and on the TextChanged event, I'm filtering from a master list and re-setting the DataContext:
private void txtSearch_TextChanged(object sender, TextChangedEventArgs e)
{
results = allContent.Where(
x => x.Content.Contains(txtSearch.Text)
).ToList();
DataContext = results;
}
That part works great. The problem is with highlighting the matched text. I've tried iterating over the ListBoxItems in various events (Loaded, ItemsChanged) but they're always empty.
Any ideas about how text highlighting might be done in a databound ListItem's child TextBox?
Here is the solution that I went with:
private void ResultsText_Loaded(object sender, RoutedEventArgs e)
{
var textBlock = sender as TextBlock;
if (txtSearch.Text.Length > 0 && textBlock.Text.Length > 0)
{
BoldText(ref textBlock, txtSearch.Text, Color.FromArgb(255, 254, 247, 71));
}
}
public static void BoldText(ref TextBlock tb, string partToBold, Color color)
{
string Text = tb.Text;
tb.Inlines.Clear();
Run r = new Run();
r.Text = Text.Substring(0, Text.IndexOf(partToBold));
tb.Inlines.Add(r);
r = new Run();
r.Text = partToBold;
r.FontWeight = FontWeights.Bold;
r.Foreground = new SolidColorBrush(color);
tb.Inlines.Add(r);
r = new Run();
r.Text = Text.Substring(Text.IndexOf(partToBold) + partToBold.Length, Text.Length - (Text.IndexOf(partToBold) + partToBold.Length));
tb.Inlines.Add(r);
}