I'm trying to do a rich text editor toolbar with 4 basic buttons (bold, italic, underline + color), here what I've got actually:
public override UIView InputAccessoryView
{
get
{
UIToolbar toolbar = new UIToolbar(new RectangleF(0, 0, 320, 30));
var fixedSpace = new UIBarButtonItem(UIBarButtonSystemItem.FixedSpace, null)
{
Width = 26
};
var flexibleSpace = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace, null);
boldItem = new UIBarButtonItem("B", UIBarButtonItemStyle.Plain, (o, e) => { GoBold(); });
italicItem = new UIBarButtonItem("I", UIBarButtonItemStyle.Plain, (o, e) => { GoItalic(); });
underlineItem = new UIBarButtonItem("U", UIBarButtonItemStyle.Plain, (o, e) => { GoUnderlined(); });
redItem = new UIBarButtonItem("R", UIBarButtonItemStyle.Plain, (o, e) => { GoRed(); });
toolbar.Items = new UIBarButtonItem[] { underlineItem, fixedSpace, italicItem, flexibleSpace, boldItem, fixedSpace, redItem };
return toolbar;
}
}
protected NSRange GetTextRange()
{
return new NSRange(
textField.GetOffsetFromPosition(textField.BeginningOfDocument, textField.SelectedTextRange.start),
textField.GetOffsetFromPosition(textField.SelectedTextRange.start, textField.SelectedTextRange.end)
);
}
protected void GoItalic()
{
NSMutableAttributedString text = new NSMutableAttributedString(textField.AttributedText);
text.AddAttribute(CTStringAttributeKey.Font, UIFont.ItalicSystemFontOfSize(20f), GetTextRange());
textField.AttributedText = text;
}
protected void GoUnderlined()
{
NSMutableAttributedString text = new NSMutableAttributedString(textField.AttributedText);
text.AddAttribute(CTStringAttributeKey.UnderlineStyle, new NSNumber((int) NSUnderlineStyle.Single), GetTextRange());
//text.AddAttribute(CTStringAttributeKey.UnderlineStyle, new NSNumber(NSUnderlineStyle.Single as int), GetTextRange());
textField.AttributedText = text;
}
protected void GoBold()
{
NSMutableAttributedString text = new NSMutableAttributedString(textField.AttributedText);
text.AddAttribute(CTStringAttributeKey.Font, UIFont.BoldSystemFontOfSize(20f), GetTextRange());
textField.AttributedText = text;
}
protected void GoRed()
{
NSMutableAttributedString text = new NSMutableAttributedString(textField.AttributedText);
text.AddAttribute(CTStringAttributeKey.UnderlineColor, UIColor.Red, GetTextRange());
textField.AttributedText = text;
}
Bold and Italic works just fine, but no way of making Underline and color works :/, I've succeded in applying underline to my selection with a crappy cast but I'd rather know how it should be done.
Seems I'm facing a casting problem, since NSUnderlineStyle.Single returns an enum where an object is expected, same goes for colors
Related
I have e CustomMapRenderer on iOS project and I want to add two more fields in the marker click.
In the CustomMKAnnotationView.cs I create a two more objects - CodeNum and AlertLevel:
using MapKit;
namespace MaritsaTundzhaForecast.iOS
{
public class CustomMKAnnotationView : MKAnnotationView
{
public string Name { get; set; }
public string Url { get; set; }
public int AlertLevel { get; set; }
public int CodeNum { get; set; }
public CustomMKAnnotationView(IMKAnnotation annotation, string id)
: base(annotation, id)
{
}
}
}
In CustomMapRenderer.cs I use this line of code to show it but when I click on the pin they do not appear:
((CustomMKAnnotationView)annotationView).AlertLevel = customPin.AlertLevel;
((CustomMKAnnotationView)annotationView).CodeNum = customPin.CodeNum;
This is the full code of GetViewForAnnotation:
protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
{
MKAnnotationView annotationView = null;
if (annotation is MKUserLocation)
return null;
var customPin = GetCustomPin(annotation as MKPointAnnotation);
if (customPin == null)
{
throw new Exception("Custom pin not found");
}
annotationView = mapView.DequeueReusableAnnotation(customPin.Name);
if (annotationView == null)
{
annotationView = new CustomMKAnnotationView(annotation, customPin.Name);
annotationView.Image = UIImage.FromFile("pin.png");
annotationView.CalloutOffset = new CGPoint(0, 0);
annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("green.png"));
((CustomMKAnnotationView)annotationView).Name = customPin.Name;
((CustomMKAnnotationView)annotationView).Url = customPin.Url;
((CustomMKAnnotationView)annotationView).AlertLevel = customPin.AlertLevel;
((CustomMKAnnotationView)annotationView).CodeNum = customPin.CodeNum;
}
annotationView.CanShowCallout = true;
return annotationView;
}
I have OnDidSelectAnnotation methods, but I don't know what to write inside to display CodeNum and AlertLevel:
void OnDidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)
{
CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
customPinView = new UIView();
if (customView.Name.Equals("Xamarin"))
{
customPinView.Frame = new CGRect(0, 0, 200, 84);
/*
var image = new UIImageView(new CGRect(0, 0, 200, 84));
image.Image = UIImage.FromFile("green.png");
customPinView.AddSubview(image);
*/
customPinView.Center = new CGPoint(0, -(e.View.Frame.Height + 75));
e.View.AddSubview(customPinView);
}
}
void OnDidDeselectAnnotationView(object sender, MKAnnotationViewEventArgs e)
{
if (!e.View.Selected)
{
customPinView.RemoveFromSuperview();
customPinView.Dispose();
customPinView = null;
}
}
I use this code to create a new label but I want to put this values from customView.AlertLevel.ToString(); inside in the info window.
void OnDidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)
{
CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
customPinView = new UIView();
if (customView.Name.Equals("Xamarin"))
{
customPinView.Frame = new CGRect(0, 0, 200, 84);
/*
var image = new UIImageView(new CGRect(0, 0, 200, 84));
image.Image = UIImage.FromFile("green.png");
customPinView.AddSubview(image);
*/
customPinView.Center = new CGPoint(0, -(e.View.Frame.Height + 75));
e.View.AddSubview(customPinView);
var label = new UILabel(new CGRect(0, 0, 200, 84));
label.Text = customView.AlertLevel.ToString();
customPinView.AddSubview(label);
}
}
This is screenshot how look now:
you need to modify the UI to display the additional data
// you will need to experiment with the Bounds to fit your UI
var label = new UILabel(new CGRect(0, 0, 100, 50));
label.Text = customView.AlertLevel;
customPinView.AddSubview(label);
This is a C# web form project I am starting with after a long time away from IDE coding...
I am trying to make a simple custom dialog box class. This is my code.
public static class Dialogo
{
public static int show ()
{
Form dialogo = new Form();
dialogo.Width = 300;
dialogo.Height = 300;
Button btnSim = new Button() { Text = "Sim", Left = 30, Width = 100 };
Button btnNao = new Button() { Text = "Não", Left = 150, Width = 100 };
dialogo.Controls.Add(btnSim);
dialogo.Controls.Add(btnNao);
dialogo.ShowDialog();
// the following two lines are the problematic ones
btnSim += new EventHandler(btnSim_Click);
btnNao += new EventHandler(btnNao_Click);
return -1;
}
}
It's underlining the text within parenthesis and the message says:
The name btnSim_Click' does not exist in the current context
The problem is that I tried to add the following in my code but it doesn't let me put it anywhere (it always says that is something wrong):
private int btnNao_Click (object sender, EventArgs e)
{
return 0;
}
private int btnSim_Click (object sender, EventArgs e)
{
return 1;
}
My objective is that each of the both buttons btnSim and btnNao return a different value (say 1 and 0).
What am I doing wrong?
EventHandler is a delegate for a method that returns void.
Your methods return int.
Try something like this:
public static int show()
{
int returnValue = -1;
using (Form dialogo = new Form())
{
dialogo.Width = 300;
dialogo.Height = 300;
Button btnSim = new Button() { Text = "Sim", Left = 30, Width = 100 };
Button btnNao = new Button() { Text = "Não", Left = 150, Width = 100 };
dialogo.Controls.Add(btnSim);
dialogo.Controls.Add(btnNao);
btnSim.Click += (s, e) => { returnValue = 0; dialogo.DialogResult = DialogResult.OK; };
btnNao.Click += (s, e) => { returnValue = 1; dialogo.DialogResult = DialogResult.OK; };
dialogo.Disposed += (s, e) =>
{
btnSim?.Dispose();
btnSim = null;
btnNao?.Dispose();
btnNao = null;
};
dialogo.ShowDialog();
}
return returnValue;
}
Hi guys I have a listview that I have made in Xamarin but not using Xamarin Forms. when I tap on a selected item it turns orange by default but I want to show a DisplayAlert when I tap on it. does anybody know how to solve this? below is my list view in C#
public string PhoneNumber;
StackLayout stackLayout = new StackLayout();
_listView = new ListView
{
ItemTemplate = new DataTemplate(() =>
{
Label nameLabel = new Label();
nameLabel.SetBinding(Label.TextProperty, "Name");
nameLabel.FontSize = 20;
Label addressLabel = new Label();
addressLabel.SetBinding(Label.TextProperty, "Address");
Label phoneLabel = new Label();
phoneLabel.SetBinding(Label.TextProperty, "Phone");
PhoneNumber = phoneLabel.Text;
return new ViewCell
{
View = new StackLayout
{
Padding = new Thickness(20, 5),
Orientation = StackOrientation.Horizontal,
Children =
{
new StackLayout
{
VerticalOptions = LayoutOptions.Center,
Spacing = 0,
Children =
{
nameLabel,
addressLabel,
phoneLabel,
}
}
}
}
};
})
};
_listView.HasUnevenRows = true;
_listView.ItemsSource = db.Table<Company>().OrderBy(x => x.Name).ToList();
stackLayout.Children.Add(_listView);
_listView.ItemTapped += _listView_ItemTapped;
Content = stackLayout;
}
private void _listView_ItemTapped(object sender, ItemTappedEventArgs e)
{
var phoneDialer = CrossMessaging.Current.PhoneDialer;
if (phoneDialer.CanMakePhoneCall)
phoneDialer.MakePhoneCall("11112222");
DisplayAlert("Phone Dial","Dialing" + e.Item.PhoneNumber, "Ok");
}
Just create ItemTapped method
_listView.ItemTapped += _listView_ItemTapped;
And implement it
private void _listView_ItemTapped(object sender, ItemTappedEventArgs e)
{
var item = e.Item as Company; //Company is your model class
DisplayAlert("Alert", item.Name, "Cancel");
}
Output screen
I want to stretch my map on a click of a toolbar button.
I succeed in that simply to go to another page (MapFullPage).
The problem is when I want on override BackButtonPressed through App.Current.Main = new MainMasterDetailPage(new MapPage()) it throwes me back, but my zoom isn't more desired zoom (when I leaved this page and went on MapFullPage), the zoom is small (I can see continents).
If I call App.Current.Main = new MapPage() it shows me the correct zoom.
Here is my two classes:
MapPage ->
public class MapPage : ContentPageCustom
{
//TKCustomMap mapView;
//TKCustomMapPin pinSelected;
DealerLocationResponseModel responseLocations;
DealerLocationResponseModel responseShops;
DealerLocationResponseModel responseStats;
DealerLocationResponseModel responseMoney;
public MapPage()
{
try
{
if (IsBusy)
return;
IsBusy = true;
this.CreateView();
}
catch (Exception ex)
{
DisplayAlert("Error", Constants.StandardError, "OK");
}
finally
{
IsBusy = false;
}
}
private async void CreateView()
{
try
{
Icon = "map-alt.png";
Title = "Locations";
var mapView = new TKCustomMap();
mapView.IsShowingUser = true;
mapView.SetBinding(TKCustomMap.CustomPinsProperty, "Pins");
mapView.SetBinding(TKCustomMap.MapClickedCommandProperty, "MapClickedCommand");
mapView.SetBinding(TKCustomMap.MapLongPressCommandProperty, "MapLongPressCommand");
mapView.SetBinding(TKCustomMap.MapCenterProperty, "MapCenter");
mapView.SetBinding(TKCustomMap.PinSelectedCommandProperty, "PinSelectedCommand");
mapView.SetBinding(TKCustomMap.SelectedPinProperty, "SelectedPin");
mapView.SetBinding(TKCustomMap.RoutesProperty, "Routes");
mapView.SetBinding(TKCustomMap.PinDragEndCommandProperty, "DragEndCommand");
mapView.SetBinding(TKCustomMap.CirclesProperty, "Circles");
mapView.SetBinding(TKCustomMap.CalloutClickedCommandProperty, "CalloutClickedCommand");
mapView.SetBinding(TKCustomMap.PolylinesProperty, "Lines");
mapView.SetBinding(TKCustomMap.PolygonsProperty, "Polygons");
mapView.SetBinding(TKCustomMap.MapRegionProperty, "MapRegion");
mapView.SetBinding(TKCustomMap.RouteClickedCommandProperty, "RouteClickedCommand");
mapView.SetBinding(TKCustomMap.RouteCalculationFinishedCommandProperty, "RouteCalculationFinishedCommand");
mapView.SetBinding(TKCustomMap.TilesUrlOptionsProperty, "TilesUrlOptions");
mapView.SetBinding(TKCustomMap.MapFunctionsProperty, "MapFunctions");
mapView.IsRegionChangeAnimated = true;
NavigationPage.SetHasBackButton(this, false);
BackgroundColor = Color.White;
responseLocations = ServiceProvider.GetDealerLocationServiceMethod(new DealerLocationRequestModel { MobilePhoneNumber = "063333333", UserIdentificator = "1234" });
if (!responseLocations.Succeeded)
{
await DisplayAlert("Greska", "Nije nadjena nijedna lokacija", "OK");
App.Current.MainPage = new HomeMasterDetail();
return;
}
List<TKCustomMapPin> pinLists = new List<TKCustomMapPin>();
foreach (var item in responseLocations.Dealers)
{
pinLists.Add(
new TKCustomMapPin
{
Image = "_mapPin_36x36",
IsCalloutClickable = true,
ShowCallout = true,
Position = new Position(item.Latitude, item.Longitude),
Title = item.LocationName + " " + item.Address,
Subtitle = item.LocationDescription
}
);
}
mapView.CustomPins = pinLists;
#region Stack and Buttons
mapView = new TKCustomMap(MapSpan.FromCenterAndRadius(mapView.CustomPins.ElementAt(1).Position, Distance.FromKilometers(2)));
mapView.CustomPins = new List<TKCustomMapPin>(pinLists);
mapView.IsShowingUser = true;
StackLayout btnCart = ElementsHelper.createImageButton("_cart_512x512.png", "Shops");
StackLayout btnStats = ElementsHelper.createImageButton("_stats_512x512.png", "Top up");
StackLayout btnMoney = ElementsHelper.createImageButton("_money_512x512.png", "Cash out");
StackLayout layout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.Center,
Children =
{
btnStats,
btnMoney,
btnCart
}
};
BoxView box1 = new BoxView { BackgroundColor = Color.Transparent, HeightRequest = Device.GetNamedSize(NamedSize.Large, typeof(Image)) * 2.5, WidthRequest = Device.GetNamedSize(NamedSize.Large, typeof(Image)) * 2.5 };
BoxView box2 = new BoxView { BackgroundColor = Color.Transparent, HeightRequest = Device.GetNamedSize(NamedSize.Large, typeof(Image)) * 2.5, WidthRequest = Device.GetNamedSize(NamedSize.Large, typeof(Image)) * 2.5 };
ActivityIndicator activityIndicator = new ActivityIndicator();
activityIndicator.Color = Constants.iPink;
activityIndicator.BindingContext = this;
activityIndicator.IsRunning = true;
activityIndicator.HeightRequest = 70;
activityIndicator.Margin = new Thickness(15, 0);
activityIndicator.SetBinding(ActivityIndicator.IsRunningProperty, "IsBusy");
activityIndicator.SetBinding(ActivityIndicator.IsVisibleProperty, "IsBusy");
layout.Children.Add(activityIndicator);
StackLayout layoutIndicator = new StackLayout { Orientation = StackOrientation.Horizontal };
layoutIndicator.Children.Add(box1);
layoutIndicator.Children.Add(activityIndicator);
layoutIndicator.Children.Add(box2);
layoutIndicator.IsVisible = false;
TapGestureRecognizer btnShopRecognizer = new TapGestureRecognizer();
btnShopRecognizer.Tapped += async (sender, e) =>
{
if (IsBusy)
return;
IsBusy = true;
layout.IsVisible = false;
layoutIndicator.IsVisible = true;
await Task.Delay(400);
responseShops = ServiceProvider.GetDealerLocationServiceMethod(new DealerLocationRequestModel { MobilePhoneNumber = "063333333", UserIdentificator = "1234" }, 1);
SetPins(mapView, responseShops);
mapView.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(responseShops.Dealers.ElementAt(1).Latitude, responseShops.Dealers.ElementAt(1).Longitude), Distance.FromKilometers(2)));
SetActiveButtonMap(btnCart, btnStats, btnMoney);
IsBusy = false;
layoutIndicator.IsVisible = false;
layout.IsVisible = true;
};
TapGestureRecognizer btnMoneyRecognizer = new TapGestureRecognizer();
btnMoneyRecognizer.Tapped += async (sender, e) =>
{
if (IsBusy)
return;
IsBusy = true;
layout.IsVisible = false;
layoutIndicator.IsVisible = true;
await Task.Delay(400);
responseMoney = ServiceProvider.GetDealerLocationServiceMethod(new DealerLocationRequestModel { MobilePhoneNumber = "063333333", UserIdentificator = "1234" }, 2);
SetPins(mapView, responseMoney);
mapView.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(responseMoney.Dealers.ElementAt(1).Latitude, responseMoney.Dealers.ElementAt(1).Longitude), Distance.FromKilometers(2)));
SetActiveButtonMap(btnMoney, btnStats, btnCart);
IsBusy = false;
layoutIndicator.IsVisible = false;
layout.IsVisible = true;
};
TapGestureRecognizer btnStatsRecognizer = new TapGestureRecognizer();
btnStatsRecognizer.Tapped += async (sender, e) =>
{
if (IsBusy)
return;
IsBusy = true;
layout.IsVisible = false;
layoutIndicator.IsVisible = true;
await Task.Delay(400);
responseStats = ServiceProvider.GetDealerLocationServiceMethod(new DealerLocationRequestModel { MobilePhoneNumber = "063333333", UserIdentificator = "1234" }, 3);
SetPins(mapView, responseStats);
mapView.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(responseStats.Dealers.ElementAt(1).Latitude, responseStats.Dealers.ElementAt(1).Longitude), Distance.FromKilometers(2)));
SetActiveButtonMap(btnStats, btnMoney, btnCart);
IsBusy = false;
layoutIndicator.IsVisible = false;
layout.IsVisible = true;
};
btnCart.GestureRecognizers.Add(btnShopRecognizer);
btnMoney.GestureRecognizers.Add(btnMoneyRecognizer);
btnStats.GestureRecognizers.Add(btnStatsRecognizer);
#endregion
RelativeLayout _baseLayout = new RelativeLayout { VerticalOptions = LayoutOptions.FillAndExpand };
_baseLayout.Children.Add(
mapView,
Constraint.RelativeToParent((parent) =>
{
return (0);
}),
Constraint.RelativeToParent((parent) =>
{
return (0);
}),
heightConstraint: Constraint.RelativeToParent((r) => r.Height),
widthConstraint: Constraint.RelativeToParent((r) => r.Width));
Func<RelativeLayout, double> getLayoutWidth = (p) => layout.Measure(_baseLayout.Width, _baseLayout.Height).Request.Width;
_baseLayout.Children.Add(layout,
Constraint.RelativeToParent((parent) => parent.Width / 2 - getLayoutWidth(parent) / 2),
Constraint.RelativeToParent((parent) =>
{
return (.8 * parent.Height);
})
);
_baseLayout.Children.Add(layoutIndicator,
Constraint.RelativeToParent((parent) => parent.Width / 2 - getLayoutWidth(parent) / 2),
Constraint.RelativeToParent((parent) =>
{
return (.8 * parent.Height);
})
);
//_baseLayout.Children.Add(activityIndicator,
//Constraint.RelativeToParent((parent) => parent.Width / 2),
//Constraint.RelativeToParent((parent) =>
//{
// return (.8 * parent.Height);
//})
//);
Constraint.RelativeToParent((parent) =>
{
return (1);
});
_baseLayout.HeightRequest = App.ScreenHeight - 200;
Content = _baseLayout;
}
catch
{
await DisplayAlert("Error", Constants.StandardError, "OK");
}
//this._baseLayout.Children.Add(
// mapView,
// Constraint.RelativeToView(autoComplete, (r, v) => v.X),
// Constraint.RelativeToView(autoComplete, (r, v) => autoComplete.HeightOfSearchBar),
// heightConstraint: Constraint.RelativeToParent((r) => r.Height - autoComplete.HeightOfSearchBar),
// widthConstraint: Constraint.RelativeToView(autoComplete, (r, v) => v.Width));
//this._baseLayout.Children.Add(
// autoComplete,
// Constraint.Constant(0),
// Constraint.Constant(0));
}
private void SetPins(TKCustomMap map, DealerLocationResponseModel dealerModel = null)
{
List<TKCustomMapPin> pinLists = new List<TKCustomMapPin>();
foreach (var item in dealerModel.Dealers)
{
pinLists.Add(
new TKCustomMapPin
{
Image = "_mapPin_36x36",
IsCalloutClickable = true,
ShowCallout = true,
Position = new Position(item.Latitude, item.Longitude),
Title = item.LocationName + " " + item.Address,
Subtitle = item.LocationDescription,
}
);
}
//map.CustomPins = null;
map.CustomPins = pinLists;
}
private void SetActiveButtonMap(StackLayout activeImage, StackLayout disabledImage1, StackLayout disabledImage2)
{
var a = ((activeImage.Children[0] as Image).Source as FileImageSource).File;
if ((!((activeImage.Children[0] as Image).Source as FileImageSource).File.ToString().Contains("_active")))
//Set active image
StartClickCustom(activeImage.Children[0] as Image);
//Remove active images
if (((disabledImage1.Children[0] as Image).Source as FileImageSource).File.ToString().Contains("_active"))
{
EndClickCustom(disabledImage1.Children[0] as Image);
}
if (((disabledImage2.Children[0] as Image).Source as FileImageSource).File.ToString().Contains("_active"))
{
EndClickCustom(disabledImage2.Children[0] as Image);
}
}
}
and MapFullPage is the same (copy/pasted) just has onBack method:
protected override bool OnBackButtonPressed()
{
App.fromBack = true;
App.Current.MainPage = new MainMasterDetailPage(new MapPage());
return true;
}
public static Boolean TextBoxValidation(TextBox txt, String AdditionalMsg)
{
if (txt.Text.Trim() == "")
{
MessageBox.Show("Please Enter " + AdditionalMsg);
return false;
}
return true;
}
This is my code; when the user does not fill some entry then a message is shown. I want something more creative: when the user does not fill some entry into the textbox, a red border blinks around my textbox and a message is shown to user just like a tooltip.
Refer to the picture I have uploaded:
I kind of wanted something like that for a while and this is what I come up with:
Since you can't set border color for TextBox, I made a UserControl with textbox inside:
public partial class UCTextBoxCustomcs : UserControl
{
private ToolTip _errorToolTip;
// keep original background color so you can change it when txet value is OK
private Color _orgBgColor;
public new Color BackColor
{
get { return _orgBgColor; }
set
{
base.BackColor = value;
_orgBgColor = value;
}
}
public new string Text
{
get { return this.txbContent.Text; }
set { this.txbContent.Text = value; }
}
public Color InvalidBgColor { get; set; }
private bool _IsValid;
public bool IsValid
{
get { return _IsValid; }
set
{
_IsValid = value;
if (value)
{
base.BackColor = _orgBgColor;
_errorToolTip.SetToolTip(this.txbContent, "");
_errorToolTip.ShowAlways = false;
_errorToolTip.Hide(this.txbContent);
}
else
{
base.BackColor = InvalidBgColor;
_errorToolTip.ShowAlways = true;
this._errorToolTip.BackColor = InvalidBgColor;
_errorToolTip.Show(this.ErrorText, this.txbContent,this.txbContent.Width +3 ,0);
}
}
}
private string _ErrorText;
public string ErrorText
{
get
{
return _ErrorText;
}
set
{
_ErrorText = value;
if (value == null || value.Length == 0) IsValid = true;
else IsValid = false;
}
}
public UCTextBoxCustomcs()
{
this._errorToolTip = new ToolTip();
// BackColor in ToolTip is ignored, so if you want to change it,
// you have to draw it yourself
this._errorToolTip.OwnerDraw = true;
_errorToolTip.Draw += new DrawToolTipEventHandler(_errorToolTip_Draw);
_errorToolTip.Popup += new PopupEventHandler(_errorToolTip_Popup);
// white background so it looks like TextBox
this.BackColor = Color.White;
InitializeComponent();
this.txbContent.BorderStyle = BorderStyle.None;
// Intelisense tells you this property isn't there, but it is
// you have to set it to false so TextBox height can be changed
// when MultiLine is set to false
this.txbContent.AutoSize = false;
this.txbContent.Multiline = false;
// Leave 1 pixel around TextBox for pseudo-border
this.Padding = new Padding(1);
this.txbContent.Dock = DockStyle.Fill;
this.InvalidBgColor = Color.Red;
this.IsValid = true;
}
void _errorToolTip_Popup(object sender, PopupEventArgs e)
{
using (Font f = new Font("Calibri", 9))
{
Size ttSize = TextRenderer.MeasureText(
_errorToolTip.GetToolTip(e.AssociatedControl), f);
e.ToolTipSize = new Size(ttSize.Width + 6, ttSize.Height + 6);
}
}
void _errorToolTip_Draw(object sender, DrawToolTipEventArgs e)
{
// In this case a simple rectangle is drawn, but you can draw whatever you want
// Draw the custom background.
e.Graphics.FillRectangle(new SolidBrush(this.InvalidBgColor), e.Bounds);
// Draw the standard border.
e.DrawBorder();
// Draw the custom text.
// The using block will dispose the StringFormat automatically.
using (StringFormat sf = new StringFormat())
{
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
sf.HotkeyPrefix = System.Drawing.Text.HotkeyPrefix.None;
sf.FormatFlags = StringFormatFlags.NoWrap;
using (Font f = new Font("Calibri", 9))
{
Rectangle textBounds = new Rectangle(
e.Bounds.Left+3,
e.Bounds.Top+3,
e.Bounds.Width-6,
e.Bounds.Height-6);
e.Graphics.DrawString(e.ToolTipText, f,
SystemBrushes.ActiveCaptionText, e.Bounds, sf);
}
}
}
protected override void OnValidating(CancelEventArgs e)
{
this.ValidateChildren();
base.OnValidating(e);
}
}
How to use:
private void ucTextBoxCustomcs1_Validating(object sender, CancelEventArgs e)
{
if (ucTextBoxCustomcs1.Text.Length == 0)
{
ucTextBoxCustomcs1.ErrorText = "Cant be empty";
}
else ucTextBoxCustomcs1.ErrorText = null;
}
It looks like this: