I want to set default value (rather than first one) in combobox through SelectedItem/SelectedText/SelectedValue (from any one way).
I have tried to resolve it through many different ways. Like I have set enum to Key Value Pair. Tried to use "SelectedIndex". It is showing '-1' while debugging. In other "selected*" options, value is 'null'. I do not know what is happening. I have attached code. Please take a look and help me to resolve it. Thank you.
ComboBox cmbxType= new ComboBox();
cmbxType.FormattingEnabled = true;
cmbxType.DropDownStyle = ComboBoxStyle.DropDownList;
cmbxType.Margin = new Padding(3, 6, 3, 3);
cmbxType.Name = "cmbxType";
cmbxType.Size = new System.Drawing.Size(200, 28);
cmbxType.TabIndex = 1;
cmbxType.DataSource = Enum.GetValues(typeof(StateType));
cmbxType.SelectedIndexChanged += new System.EventHandler(cmbxType_SelectedIndexChanged);
cmbxType.ValueMember = (workflowRows).ToString();
cmbxType.SelectedValue = 2
PS: I am creating this combobox after creating form and the problematic case is with enum only.
According to this Stack Overflow question you can only set the selected item after the data bindings are assigned. If you select the item when the OnLoad event occures it should work. Below is a working example.
using System;
using System.Windows.Forms;
namespace WindowsFormsApp
{
static class Program
{
internal enum StateType
{
State1,
State2,
State3
}
internal class DemoForm : Form
{
ComboBox cmbxType = new ComboBox();
public DemoForm()
{
cmbxType.DataSource = Enum.GetValues(typeof(StateType));
Controls.Add(cmbxType);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
cmbxType.SelectedItem = StateType.State3;
}
}
[STAThread]
static void Main()
{
Application.Run(new DemoForm());
}
}
}
I am using below method to validate data within textbox in groupbox
so for improvement of user Feedback for example
message text Please enter First Name
where First Name is the label for textbox, so I used Textbox.Tag to store the name of textbox to achieve it since there is no link between the Textbox and it is Label
I search and found that I can use the Tag property to store anything but I wan to be sure of using it by the I told you about
Is there any problem with that ?
public int ValidateData()
{
foreach (Control cont in GB_PatientInfo.Controls)
{
if (cont is TextBox)
{
if (string.IsNullOrWhiteSpace(cont.Text.Trim()))
{
MessageBox.Show("enter data " + cont.Tag, "Message", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading);
cont.BackColor = Color.Red;
cont.Focus();
return -1;
}
}
}
return 1;
}
Thanks
As you have read, you can store any type that derives from object (i.e. everything) in the Control.Tag property so storing the name of a label is fine.
The use of the Tag property does not influence your application. You can store whatever you want in there with no problem.
As it's already mentioned in other answers, it's OK to use Tag property to store any kind of additional information about the control, including a display name.
But have you ever noticed how ToolTip lets you to set ToolTip for your control at design-time?
A ToolTip, ErrorProvider or HelpProvider are examples of extender provider components. They add some properties to the controls at design-time. You also can create such component for DisplayName by implementing IExtenderProvider.
Example
The following code shows you how easily you can create a component called DisplayNameExtender. When you drop an instance of this component on the form, then a new property will be added to design-time of controls, you can set the value to the property
at design-time: DisplayName on diaplayNameExtender1.
Then at run-time, whenever you want to get the value of DisplayName for a control, it's enough to find it this way:
var displayName = displayNameExtender1.GetDisplayName(control);
Here is the code for DisplayNameExtender component:
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
[ProvideProperty("DisplayName", typeof(Control))]
public class DisplayNameExtender : Component, IExtenderProvider
{
private Hashtable displayNameValues = new Hashtable();
public bool CanExtend(object extendee)
{
return (extendee is Control && !(extendee is Form));
}
public string GetDisplayName(Control control)
{
if (displayNameValues.ContainsKey(control))
return (string)displayNameValues[control];
return null;
}
public void SetDisplayName(Control control, string value)
{
if (string.IsNullOrEmpty(value))
displayNameValues.Remove(control);
else
displayNameValues[control] = value;
}
}
Old Title: Prevent dynamically created control from retaining value
Old Info:
The reason I need to do this is because I am trying to create a work around for a required field validator for an Image control. The way my code works is I have a Image control beside a Button, a user clicks on the button and then is prompted to upload an image. I need to ensure that an image is uploaded before the user can move onto the next stage.
Since there is no required field validator for an image control, I created a textbox which is suppose to display the imageURL of the image control every time the image control is recreated on postbacks. However, the textbox always retains the value from the initial creation of the control.
* Note: all controls on the page are dynamically created.
The first thing I do is create the image control and add it to an HTML Table. This works fine. Right after that I find the table cell and add the textbox to the cell that has an image control:
HtmlTableCell tc = (HtmlTableCell)customProperties.FindControl("tcControl_" + (i + 1).ToString());
RadBinaryImage rbi = (RadBinaryImage)customProperties.FindControl("CustomControl" + (i + 1).ToString());
TextBox photoValue = new TextBox();
photoValue.ID = "CustomControl" + (i + 1).ToString() + "_txt";
photoValue.Text = rbi.imageUrl;
This occurs everytime I create all the controls. For all the controls they all retain their values, this is the only control which I don't want this to happen. Does anyone know of how this can be done? Or another way of validating an image control?
Thanks for your time,
All comments/answers are appreciated (:
SOLVED:
I created a modified version of a checkboxlist required field validator that I found here.
Here is the code: I replaced the namespace with ######## for security reasons.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using Telerik.Web.UI;
namespace #######################################
{
public class RequiredFieldValidatorForImages :
System.Web.UI.WebControls.BaseValidator
{
private Control _ctrl;
public RequiredFieldValidatorForImages()
{
base.EnableClientScript = false;
}
protected override bool ControlPropertiesValid()
{
Control ctrl = FindControl(ControlToValidate);
if (ctrl != null)
{
_ctrl = (Control)ctrl;
return (_ctrl != null);
}
else
return false; // raise exception
}
protected override bool EvaluateIsValid()
{
try
{
Image rbi = (Image)_ctrl;
return rbi.ImageUrl != "~/images/noimages.jpg";
}
catch
{
RadBinaryImage rbi = (RadBinaryImage)_ctrl;
return rbi.ImageUrl != "~/images/noimages.jpg";
}
}
}
}
Solved:
I created a modified version of a checkboxlist required field validator that I found here.
Here is the code: I replaced the namespace with ######## for security reasons.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using Telerik.Web.UI;
namespace #######################################
{
public class RequiredFieldValidatorForImages :
System.Web.UI.WebControls.BaseValidator
{
private Control _ctrl;
public RequiredFieldValidatorForImages()
{
base.EnableClientScript = false;
}
protected override bool ControlPropertiesValid()
{
Control ctrl = FindControl(ControlToValidate);
if (ctrl != null)
{
_ctrl = (Control)ctrl;
return (_ctrl != null);
}
else
return false; // raise exception
}
protected override bool EvaluateIsValid()
{
try
{
Image rbi = (Image)_ctrl;
return rbi.ImageUrl != "~/images/noimages.jpg";
}
catch
{
RadBinaryImage rbi = (RadBinaryImage)_ctrl;
return rbi.ImageUrl != "~/images/noimages.jpg";
}
}
}
}
To do DataBinding of the Document in a WPF RichtextBox, I saw 2 solutions so far, which are to derive from the RichtextBox and add a DependencyProperty, and also the solution with a "proxy".
Neither the first or the second are satisfactory. Does somebody know another solution, or instead, a commercial RTF control which is capable of DataBinding? The normal TextBox is not an alternative, since we need text formatting.
Any idea?
There is a much easier way!
You can easily create an attached DocumentXaml (or DocumentRTF) property which will allow you to bind the RichTextBox's document. It is used like this, where Autobiography is a string property in your data model:
<TextBox Text="{Binding FirstName}" />
<TextBox Text="{Binding LastName}" />
<RichTextBox local:RichTextBoxHelper.DocumentXaml="{Binding Autobiography}" />
Voila! Fully bindable RichTextBox data!
The implementation of this property is quite simple: When the property is set, load the XAML (or RTF) into a new FlowDocument. When the FlowDocument changes, update the property value.
This code should do the trick:
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
public class RichTextBoxHelper : DependencyObject
{
public static string GetDocumentXaml(DependencyObject obj)
{
return (string)obj.GetValue(DocumentXamlProperty);
}
public static void SetDocumentXaml(DependencyObject obj, string value)
{
obj.SetValue(DocumentXamlProperty, value);
}
public static readonly DependencyProperty DocumentXamlProperty =
DependencyProperty.RegisterAttached(
"DocumentXaml",
typeof(string),
typeof(RichTextBoxHelper),
new FrameworkPropertyMetadata
{
BindsTwoWayByDefault = true,
PropertyChangedCallback = (obj, e) =>
{
var richTextBox = (RichTextBox)obj;
// Parse the XAML to a document (or use XamlReader.Parse())
var xaml = GetDocumentXaml(richTextBox);
var doc = new FlowDocument();
var range = new TextRange(doc.ContentStart, doc.ContentEnd);
range.Load(new MemoryStream(Encoding.UTF8.GetBytes(xaml)),
DataFormats.Xaml);
// Set the document
richTextBox.Document = doc;
// When the document changes update the source
range.Changed += (obj2, e2) =>
{
if (richTextBox.Document == doc)
{
MemoryStream buffer = new MemoryStream();
range.Save(buffer, DataFormats.Xaml);
SetDocumentXaml(richTextBox,
Encoding.UTF8.GetString(buffer.ToArray()));
}
};
}
});
}
The same code could be used for TextFormats.RTF or TextFormats.XamlPackage. For XamlPackage you would have a property of type byte[] instead of string.
The XamlPackage format has several advantages over plain XAML, especially the ability to include resources such as images, and it is more flexible and easier to work with than RTF.
It is hard to believe this question sat for 15 months without anyone pointing out the easy way to do this.
I know this is an old post, but check out the Extended WPF Toolkit. It has a RichTextBox that supports what you are tryign to do.
I can give you an ok solution and you can go with it, but before I do I'm going to try to explain why Document is not a DependencyProperty to begin with.
During the lifetime of a RichTextBox control, the Document property generally doesn't change. The RichTextBox is initialized with a FlowDocument. That document is displayed, can be edited and mangled in many ways, but the underlying value of the Document property remains that one instance of the FlowDocument. Therefore, there is really no reason it should be a DependencyProperty, ie, Bindable. If you have multiple locations that reference this FlowDocument, you only need the reference once. Since it is the same instance everywhere, the changes will be accessible to everyone.
I don't think FlowDocument supports document change notifications, though I am not sure.
That being said, here's a solution. Before you start, since RichTextBox doesn't implement INotifyPropertyChanged and Document is not a DependencyProperty, we have no notifications when the RichTextBox's Document property changes, so the binding can only be OneWay.
Create a class that will provide the FlowDocument. Binding requires the existence of a DependencyProperty, so this class inherits from DependencyObject.
class HasDocument : DependencyObject
{
public static readonly DependencyProperty DocumentProperty =
DependencyProperty.Register("Document",
typeof(FlowDocument),
typeof(HasDocument),
new PropertyMetadata(new PropertyChangedCallback(DocumentChanged)));
private static void DocumentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
Debug.WriteLine("Document has changed");
}
public FlowDocument Document
{
get { return GetValue(DocumentProperty) as FlowDocument; }
set { SetValue(DocumentProperty, value); }
}
}
Create a Window with a rich text box in XAML.
<Window x:Class="samples.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Flow Document Binding" Height="300" Width="300"
>
<Grid>
<RichTextBox Name="richTextBox" />
</Grid>
</Window>
Give the Window a field of type HasDocument.
HasDocument hasDocument;
Window constructor should create the binding.
hasDocument = new HasDocument();
InitializeComponent();
Binding b = new Binding("Document");
b.Source = richTextBox;
b.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(hasDocument, HasDocument.DocumentProperty, b);
If you want to be able to declare the binding in XAML, you would have to make your HasDocument class derive from FrameworkElement so that it can be inserted into the logical tree.
Now, if you were to change the Document property on HasDocument, the rich text box's Document will also change.
FlowDocument d = new FlowDocument();
Paragraph g = new Paragraph();
Run a = new Run();
a.Text = "I showed this using a binding";
g.Inlines.Add(a);
d.Blocks.Add(g);
hasDocument.Document = d;
I have tuned up previous code a little bit.
First of all range.Changed hasn't work for me.
After I changed range.Changed to richTextBox.TextChanged it turns out that TextChanged event handler can invoke SetDocumentXaml recursively, so I've provided protection against it. I also used XamlReader/XamlWriter instead of TextRange.
public class RichTextBoxHelper : DependencyObject
{
private static HashSet<Thread> _recursionProtection = new HashSet<Thread>();
public static string GetDocumentXaml(DependencyObject obj)
{
return (string)obj.GetValue(DocumentXamlProperty);
}
public static void SetDocumentXaml(DependencyObject obj, string value)
{
_recursionProtection.Add(Thread.CurrentThread);
obj.SetValue(DocumentXamlProperty, value);
_recursionProtection.Remove(Thread.CurrentThread);
}
public static readonly DependencyProperty DocumentXamlProperty = DependencyProperty.RegisterAttached(
"DocumentXaml",
typeof(string),
typeof(RichTextBoxHelper),
new FrameworkPropertyMetadata(
"",
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
(obj, e) => {
if (_recursionProtection.Contains(Thread.CurrentThread))
return;
var richTextBox = (RichTextBox)obj;
// Parse the XAML to a document (or use XamlReader.Parse())
try
{
var stream = new MemoryStream(Encoding.UTF8.GetBytes(GetDocumentXaml(richTextBox)));
var doc = (FlowDocument)XamlReader.Load(stream);
// Set the document
richTextBox.Document = doc;
}
catch (Exception)
{
richTextBox.Document = new FlowDocument();
}
// When the document changes update the source
richTextBox.TextChanged += (obj2, e2) =>
{
RichTextBox richTextBox2 = obj2 as RichTextBox;
if (richTextBox2 != null)
{
SetDocumentXaml(richTextBox, XamlWriter.Save(richTextBox2.Document));
}
};
}
)
);
}
<RichTextBox>
<FlowDocument PageHeight="180">
<Paragraph>
<Run Text="{Binding Text, Mode=TwoWay}"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
This seems to be the easiest way by far and isn't displayed in any of these answers.
In the view model just have the Text variable.
Create a UserControl which has a RichTextBox named RTB. Now add the following dependency property:
public FlowDocument Document
{
get { return (FlowDocument)GetValue(DocumentProperty); }
set { SetValue(DocumentProperty, value); }
}
public static readonly DependencyProperty DocumentProperty =
DependencyProperty.Register("Document", typeof(FlowDocument), typeof(RichTextBoxControl), new PropertyMetadata(OnDocumentChanged));
private static void OnDocumentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
RichTextBoxControl control = (RichTextBoxControl) d;
FlowDocument document = e.NewValue as FlowDocument;
if (document == null)
{
control.RTB.Document = new FlowDocument(); //Document is not amused by null :)
}
else
{
control.RTB.Document = document;
}
}
This solution is probably that "proxy" solution you saw somewhere.. However.. RichTextBox simply does not have Document as DependencyProperty... So you have to do this in another way...
HTH
Most of my needs were satisfied by this answer https://stackoverflow.com/a/2989277/3001007 by krzysztof. But one issue with that code (i faced was), the binding won't work with multiple controls. So I changed _recursionProtection with a Guid based implementation. So it's working for Multiple controls in same window as well.
public class RichTextBoxHelper : DependencyObject
{
private static List<Guid> _recursionProtection = new List<Guid>();
public static string GetDocumentXaml(DependencyObject obj)
{
return (string)obj.GetValue(DocumentXamlProperty);
}
public static void SetDocumentXaml(DependencyObject obj, string value)
{
var fw1 = (FrameworkElement)obj;
if (fw1.Tag == null || (Guid)fw1.Tag == Guid.Empty)
fw1.Tag = Guid.NewGuid();
_recursionProtection.Add((Guid)fw1.Tag);
obj.SetValue(DocumentXamlProperty, value);
_recursionProtection.Remove((Guid)fw1.Tag);
}
public static readonly DependencyProperty DocumentXamlProperty = DependencyProperty.RegisterAttached(
"DocumentXaml",
typeof(string),
typeof(RichTextBoxHelper),
new FrameworkPropertyMetadata(
"",
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
(obj, e) =>
{
var richTextBox = (RichTextBox)obj;
if (richTextBox.Tag != null && _recursionProtection.Contains((Guid)richTextBox.Tag))
return;
// Parse the XAML to a document (or use XamlReader.Parse())
try
{
string docXaml = GetDocumentXaml(richTextBox);
var stream = new MemoryStream(Encoding.UTF8.GetBytes(docXaml));
FlowDocument doc;
if (!string.IsNullOrEmpty(docXaml))
{
doc = (FlowDocument)XamlReader.Load(stream);
}
else
{
doc = new FlowDocument();
}
// Set the document
richTextBox.Document = doc;
}
catch (Exception)
{
richTextBox.Document = new FlowDocument();
}
// When the document changes update the source
richTextBox.TextChanged += (obj2, e2) =>
{
RichTextBox richTextBox2 = obj2 as RichTextBox;
if (richTextBox2 != null)
{
SetDocumentXaml(richTextBox, XamlWriter.Save(richTextBox2.Document));
}
};
}
)
);
}
For completeness sake, let me add few more lines from original answer https://stackoverflow.com/a/2641774/3001007 by ray-burns. This is how to use the helper.
<RichTextBox local:RichTextBoxHelper.DocumentXaml="{Binding Autobiography}" />
Here is my solution based on Ray Burns answer with DataBinding and conversion of a XAML-string to a RichTextBox-Document:
ViewModel
TestText = #"<FlowDocument xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""><Paragraph><Bold>Hello World!</Bold></Paragraph></FlowDocument>";
View
<RichTextBox local:RichTextBoxHelper.DocumentXaml="{Binding TestText}"/>
RichTextBoxHelper
public class RichTextBoxHelper : DependencyObject
{
public static string GetDocumentXaml(DependencyObject obj) { return (string) obj.GetValue(DocumentXamlProperty); }
public static void SetDocumentXaml(DependencyObject obj,
string value)
{
obj.SetValue(DocumentXamlProperty, value);
}
public static readonly DependencyProperty DocumentXamlProperty = DependencyProperty.RegisterAttached
(
"DocumentXaml",
typeof(string),
typeof(RichTextBoxHelper),
new FrameworkPropertyMetadata
{
BindsTwoWayByDefault = true,
PropertyChangedCallback = (obj,
e) =>
{
var richTextBox = (RichTextBox) obj;
var xaml = GetDocumentXaml(richTextBox);
Stream sm = new MemoryStream(Encoding.UTF8.GetBytes(xaml));
richTextBox.Document = (FlowDocument) XamlReader.Load(sm);
sm.Close();
}
}
);
}
Here's a VB.Net version of Lolo's answer:
Public Class RichTextBoxHelper
Inherits DependencyObject
Private Shared _recursionProtection As New HashSet(Of System.Threading.Thread)()
Public Shared Function GetDocumentXaml(ByVal depObj As DependencyObject) As String
Return DirectCast(depObj.GetValue(DocumentXamlProperty), String)
End Function
Public Shared Sub SetDocumentXaml(ByVal depObj As DependencyObject, ByVal value As String)
_recursionProtection.Add(System.Threading.Thread.CurrentThread)
depObj.SetValue(DocumentXamlProperty, value)
_recursionProtection.Remove(System.Threading.Thread.CurrentThread)
End Sub
Public Shared ReadOnly DocumentXamlProperty As DependencyProperty = DependencyProperty.RegisterAttached("DocumentXaml", GetType(String), GetType(RichTextBoxHelper), New FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender Or FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Sub(depObj, e)
RegisterIt(depObj, e)
End Sub))
Private Shared Sub RegisterIt(ByVal depObj As System.Windows.DependencyObject, ByVal e As System.Windows.DependencyPropertyChangedEventArgs)
If _recursionProtection.Contains(System.Threading.Thread.CurrentThread) Then
Return
End If
Dim rtb As RichTextBox = DirectCast(depObj, RichTextBox)
Try
rtb.Document = Markup.XamlReader.Parse(GetDocumentXaml(rtb))
Catch
rtb.Document = New FlowDocument()
End Try
' When the document changes update the source
AddHandler rtb.TextChanged, AddressOf TextChanged
End Sub
Private Shared Sub TextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
Dim rtb As RichTextBox = TryCast(sender, RichTextBox)
If rtb IsNot Nothing Then
SetDocumentXaml(sender, Markup.XamlWriter.Save(rtb.Document))
End If
End Sub
End Class
This VB.Net version works for my situation. I removed thread collection semaphore, instead using RemoveHandler and AddHandler. Also, since a FlowDocument can only be bound to one RichTextBox at a time, I put in a check that the RichTextBox's IsLoaded=True. Let's begin with how I used the class in a MVVM app which uses ResourceDictionary instead of Window.
' Loaded and Unloaded events seems to be the only way to initialize a control created from a Resource Dictionary
' Loading document here because Loaded is the last available event to create a document
Private Sub Rtb_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
' only good place to initialize RichTextBox.Document with DependencyProperty
Dim rtb As RichTextBox = DirectCast(sender, RichTextBox)
Try
rtb.Document = RichTextBoxHelper.GetDocumentXaml(rtb)
Catch ex As Exception
Debug.WriteLine("Rtb_Loaded: Message:" & ex.Message)
End Try
End Sub
' Loaded and Unloaded events seems to be the only way to initialize a control created from a Resource Dictionary
' Free document being held by RichTextBox.Document by assigning New FlowDocument to RichTextBox.Document. Otherwise we'll see an of "Document belongs to another RichTextBox"
Private Sub Rtb_Unloaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim rtb As RichTextBox = DirectCast(sender, RichTextBox)
Dim fd As New FlowDocument
RichTextBoxHelper.SetDocumentXaml(rtb, fd)
Try
rtb.Document = fd
Catch ex As Exception
Debug.WriteLine("PoemDocument.PoemDocumentView.PoemRtb_Unloaded: Message:" & ex.Message)
End Try
End Sub
Public Class RichTextBoxHelper
Inherits DependencyObject
Public Shared Function GetDocumentXaml(ByVal depObj As DependencyObject) As FlowDocument
Return depObj.GetValue(DocumentXamlProperty)
End Function
Public Shared Sub SetDocumentXaml(ByVal depObj As DependencyObject, ByVal value As FlowDocument)
depObj.SetValue(DocumentXamlProperty, value)
End Sub
Public Shared ReadOnly DocumentXamlProperty As DependencyProperty = DependencyProperty.RegisterAttached("DocumentXaml", GetType(FlowDocument), GetType(RichTextBoxHelper), New FrameworkPropertyMetadata(Nothing, FrameworkPropertyMetadataOptions.AffectsRender Or FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Sub(depObj, e)
RegisterIt(depObj, e)
End Sub))
Private Shared Sub RegisterIt(ByVal depObj As System.Windows.DependencyObject, ByVal e As System.Windows.DependencyPropertyChangedEventArgs)
Dim rtb As RichTextBox = DirectCast(depObj, RichTextBox)
If rtb.IsLoaded Then
RemoveHandler rtb.TextChanged, AddressOf TextChanged
Try
rtb.Document = GetDocumentXaml(rtb)
Catch ex As Exception
Debug.WriteLine("RichTextBoxHelper.RegisterIt: ex:" & ex.Message)
rtb.Document = New FlowDocument()
End Try
AddHandler rtb.TextChanged, AddressOf TextChanged
Else
Debug.WriteLine("RichTextBoxHelper: Unloaded control ignored:" & rtb.Name)
End If
End Sub
' When a RichTextBox Document changes, update the DependencyProperty so they're in sync.
Private Shared Sub TextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
Dim rtb As RichTextBox = TryCast(sender, RichTextBox)
If rtb IsNot Nothing Then
SetDocumentXaml(sender, rtb.Document)
End If
End Sub
End Class
Guys why bother with all the faff. This works perfectly. No code required
<RichTextBox>
<FlowDocument>
<Paragraph>
<Run Text="{Binding Mytextbinding}"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
I have created a WindowsFormControlLibrary porject. It works fine, I can drop it on the forms,call its methods,etc ...
but now as a property of it, I am passing the name of a Label to it. and I want this custom control to be able to use that label name and for example change its font to bold .
so the question is that if I have a WinForm and I have a Label on that form and my custom control on that form, then how can I tell my custom control to do something with that label which I am passing its name to it?
Instead of sending in the name of the label, send in a reference to the actual label and then the custom control can both read the name if it needs to and change the label's font and other properties.
Be careful though, it can quickly get messy to keep track of what's happening if various forms and controls change controls on other forms etc.
Edit: Added code to do what you ask for in the comments
Code isn't tested so it might not be completely correct, but something similar to this should work.
foreach (Control c in Parent.Controls)
{
if (c is Label)
{
Label l = (Label)c;
// do stuff to label l
}
}
First, if you wish to access a Control from your UserControl, you will need to use the FindForm() method.
Second, you will be required to expose your TextBox control, for example, through a property of your form.
Then, you would need to know the type of this Form returned by this FindForm() method.
Once you know it, you need to type-cast this result to the correct type.
So, here a sample untested pseudo-code to give you the idea:
public partial class MyMainForm {
private TextBox textBox1;
public MyMainForm() {
textBox1 = new Textbox();
textBox1.Name = #"textBox1";
textBox1.Location = new Point(10, 10);
textBox1.Size = new Size(150, 23);
this.Controls.Add(textBox1);
}
public Font MyTextBoxFont {
get {
return textBox1.Font;
} set {
if (value == null) return;
textbox1.Font = value;
}
}
}
Then, assuming you have dropped your control on your form, your UserControl could have a property like so:
public partial class MyUserControl {
private Form GetContainerForm {
get {
return this.FindForm();
}
}
// And later on, where you need to set your TextBox's font:
private void SetContainerInputFieldFont(Font f) {
if (GetContainerForm == null) return; // Or throw, depending on what you need to do.
((MyMainForm)GetContainerForm).MyTextBoxFont = f
}
}
cool :) I just added a get set public property of type Label... it automatically lists all the label on the form.