I have a Xamarin.Forms (v5.0.0.2515) project.
I have encountered this strange behavior using this scenario:
I have a view with 5 rectangles. RadiusX/RadiusY for each rectangle is 20.
I assign this view to a ContentView and everything looks normal (Fig. 1)
I assign another view to the ContentView
I assign back the view to the ContentView and rounded borders are gone (Fig. 2)
What can cause this issue?
This is a sample code to reproduce the issue.
using Xamarin.Forms;
namespace App
{
public class SamplePage : ContentPage
{
public SamplePage()
{
var grid = new Grid
{
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Star }
}
};
var btn = new Button { Text = "Replace the view!" };
Grid.SetRow(btn, 0);
grid.Children.Add(btn);
var rect = new Xamarin.Forms.Shapes.Rectangle
{
RadiusX = 20,
RadiusY = 20,
Fill = Brush.Azure,
StrokeThickness = 3,
Stroke = Brush.Black
};
var cv = new ContentView { Content = rect };
Grid.SetRow(cv, 1);
grid.Children.Add(cv);
btn.Clicked += (_, __) =>
{
cv.Content = new Label();
cv.Content = rect;
};
Content = grid;
}
}
}
Thanks.
Fig. 1
Fig. 2
According to your demo you provided, I found that the code cv.Content = new Label(); caused the problem. I changed the demo and you can check.
public partial class MainPage : ContentPage
{
public MainPage()
{
var grid = new Grid
{
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Star }
}
};
var btn = new Button { Text = "Replace the view!" };
Grid.SetRow(btn, 0);
grid.Children.Add(btn);
var rect = new Xamarin.Forms.Shapes.Rectangle
{
RadiusX = 50,
RadiusY = 10,
Fill = Brush.Azure,
StrokeThickness = 10,
Stroke = Brush.Black
};
var rect2 = new Xamarin.Forms.Shapes.Rectangle
{
RadiusX = 20,
RadiusY = 20,
Fill = Brush.Azure,
StrokeThickness = 3,
Stroke = Brush.Black
};
var cv = new ContentView {Content = rect2};
Grid.SetRow(cv, 1);
grid.Children.Add(cv);
btn.Clicked += (_,__) =>
{
cv.Content = rect;
};
Content = grid;
}
}
}
Related
I have a tabbedPage where I'm assigning text and icons for each tab as follows:
this.Children.Add(new SignaturesTab() { Title = "Signature" , Icon
= "sign_new#2x.png" });
this.Children.Add(new PhotosTab() { Title = "Photos", Icon =
"image_new#2x.png" });
On my iPhone, icon appears top of the label in the bar for each tab.
Code in Tab Renderer:
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
TabBar.TintColor = new UIColor(red: 0.23f, green: 0.56f, blue: 0.20f, alpha: 1.0f);
TabBar.UnselectedItemTintColor = new UIColor(red: 0.34f, green: 0.34f, blue: 0.34f, alpha: 1.0f);
}
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
if (TabBar.Items == null) return;
TabBar.SelectedImageTintColor = new UIColor(red: 0.23f, green: 0.56f, blue: 0.20f, alpha: 1.0f);
foreach (var uiTabBarItem in TabBar.Items)
{
var fontSize = new UITextAttributes(){ Font = UIFont.SystemFontOfSize(13)};
uiTabBarItem.SetTitleTextAttributes(fontSize, UIControlState.Normal);
}
}
Is there a way to provide spacing/margin between icon and label and to the borders.
Thanks
Using UIOffset and UIEdgeInsets can modify posittion of Title and Image in TabBarItem .
TabBarItem.TitlePositionAdjustment = new UIOffset(0, 1);
//UIOffset:Represents a position offset. UIOffset(nfloat horizontal, nfloat vertical);
TabBarItem.ImageInsets = new UIEdgeInsets(0, 0, 5, 0);
//Mean: UIEdgeInsets(nfloat top, nfloat left, nfloat bottom, nfloat right);
Modifying paramaters inside UIOffset and UIEdgeInsets to fit your want.
=============================Update==============================
Changing tab bar item icon color :
UITabBar.Appearance.SelectedImageTintColor = UIColor.Yellow;
//selected color ,this will change the whole tabbar item
Just four items be modified :
for (int i = 0; i < 4; i++)
{
var fontSize = new UITextAttributes(){ Font = UIFont.SystemFontOfSize(13)};
uiTabBarItem.SetTitleTextAttributes(fontSize, UIControlState.Normal);
uiTabBarItem.TitlePositionAdjustment = new UIOffset(0, 1);
uiTabBarItem.ImageInsets = new UIEdgeInsets(0, 0, 5, 0);
}
I make a trick with IBDesignable for doing that.
may it useful for you
import UIKit
#IBDesignable
class CustomTabBarItem: UITabBarItem {
#IBInspectable var titlePosition: CGSize = CGSize(width: 0, height: 0) {
didSet {
titlePositionAdjustment = UIOffset(horizontal: titlePosition.width, vertical: titlePosition.height)
}
}
#IBInspectable var imageInset: CGRect = CGRect(x: 0, y: 0, width: 0, height: 0) {
didSet {
imageInsets = UIEdgeInsets(top: imageInset.origin.x, left: imageInset.origin.y, bottom: imageInset.size.width, right: imageInset.size.height)
}
}
}
I'm developing an IOS Application using Xamarin.Forms and in that I've customized the toolbar color to Gradient color using custom renderers.But,After this the Icons
color is changed as per the toolbar color and how to set the title text to white colour.Here is the renderer I'm using for toolbar customization
public class NavigationPageGradientHeaderRenderer:NavigationRenderer
{
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
var control = (NavigationPageGradientHeader)this.Element;
var gradientLayer = new CAGradientLayer();
gradientLayer.Bounds = NavigationBar.Bounds;
gradientLayer.Colors = new CGColor[] { control.RightColor.ToCGColor(), control.LeftColor.ToCGColor() };
gradientLayer.StartPoint = new CGPoint(0.0, 0.5);
gradientLayer.EndPoint = new CGPoint(1.0, 0.5);
UIGraphics.BeginImageContext(gradientLayer.Bounds.Size);
gradientLayer.RenderInContext(UIGraphics.GetCurrentContext());
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
NavigationBar.SetBackgroundImage(image, UIBarMetrics.Default);
}
}
After applying this the Icons look like this:
enter image description here
But I want the images background to be transparent like this:
enter image description here
and the title textcolor should be white.
How can I achieve this.Can anyone please help me with this.
Thank you
You can set the property in CustomRenderer
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
var control = (MyNativePage)Element;
var gradientLayer = new CAGradientLayer();
gradientLayer.Bounds = NavigationBar.Bounds;
gradientLayer.Colors = new CGColor[] { UIColor.Red.CGColor,UIColor.White.CGColor };
gradientLayer.StartPoint = new CGPoint(0.0, 0.5);
gradientLayer.EndPoint = new CGPoint(1.0, 0.5);
UIGraphics.BeginImageContext(gradientLayer.Bounds.Size);
gradientLayer.RenderInContext(UIGraphics.GetCurrentContext());
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
NavigationBar.SetBackgroundImage(image, UIBarMetrics.Default);
NavigationBar.TintColor = UIColor.White;
NavigationBar.TitleTextAttributes = new UIStringAttributes() { ForegroundColor =UIColor.White};
}
If you create an NavigationPage, then you can use like this
var myHomePage = new NavigationPage(dashboardPage){
Tint = Color.Red // put your color here };
You can set common color from App.xaml.cs;
public App()
{
InitializeComponent();
// MainPage = new MainPage();
MainPage = new RESTAPICallApp.Controllers.HomePage();
NavigationPage navigationRootPage = new NavigationPage(new RESTAPICallApp.Controllers.HomePage());
navigationRootPage.BarBackgroundColor = Color.LightSeaGreen;
navigationRootPage.BarTextColor = Color.Wheat;
MainPage = navigationRootPage;
}
For native Xamarin.iOS add this code in 'didFinishLaunchingWithOptions' method on AppDelegate.cs;
UINavigationBar.Appearance.Translucent = false;
UINavigationBar.appearance().barTintColor = UIColor.White
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes() {
TextColor = UIColor.White,
TextShadowColor = UIColor.Clear
});
I'm not able to link the xamarin forms custom control in the content page.
Have created the following xamarin custom control "AlertMessage",
public class AlertMessage:ContentView
{
private Frame _frame;
private Grid _alertGrid;
private StackLayout _alertLayout, _alertLayoutContent;
private BoxView _alertBoxView;
private Label _alertMessage;
public static readonly BindableProperty TitleProperty = BindableProperty.Create("Title", typeof(string), typeof(AlertMessage), default(string));
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(AlertMessage), default(string));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public AlertMessage()
{
InitLayout();
}
public void InitLayout()
{
_alertGrid = new Grid { Padding = 0 };
_alertGrid.RowDefinitions.Add(new RowDefinition
{
Height = GridLength.Star
});
_alertGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = 8 });
_alertGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
_alertLayout = new StackLayout
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Constants.MMSGAlertBackgroundColor,
Padding = 0
};
_alertBoxView = new BoxView
{
Color = Constants.MMSGAlertTextColor,
VerticalOptions = LayoutOptions.FillAndExpand
};
_alertLayout.Children.Add(_alertBoxView);
_alertLayoutContent = new StackLayout
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Padding = 16
};
_alertMessage = new Label
{
Text = Text,
TextColor = Constants.MMSGAlertTextColor
};
_alertLayoutContent.Children.Add(_alertMessage);
_alertGrid.Children.Add(_alertLayout, 0, 0);
_alertGrid.Children.Add(_alertLayoutContent, 1, 0);
_frame = new Frame
{
OutlineColor = Constants.MMSGAlertBorderColor,
BackgroundColor = Constants.MMSGAlertBackgroundColor,
Padding = new Thickness(2, 2, 0, 2),
HasShadow = false,
Content = _alertGrid,
VerticalOptions = LayoutOptions.FillAndExpand
};
this.Content = _frame;
}
}
I'm trying to render this custom control in the content page using the c# code,
var alertMessage = new AlertMessage
{
Text = ViewModel.AlertReviewMessage,
Title = "Please review"
};
I'm getting the following build error, on rendering this custom control in the content page.
Severity Code Description Project File Line Suppression State
Error Can't resolve the reference 'APP.Mobile.CustomControls.AlertText', referenced from the method 'System.Object APP.Mobile.StatusSummaryContentPage::<GetDataTemplate>b__7_0()' in 'MMSG.Mobile, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. RemServ.Mobile.iOS
Please let me know what link am i missing here to add a custom control to a content page
Your content view is missing InitializeComponent(); in the constructor.It should be like below
public AlertView()
{
InitializeComponent();
Content.BindingContext = this;
}
I hope you have added reference to the shared project from custom controls project. using APP.Mobile.CustomControls;
Also you should add [XamlCompilation(XamlCompilationOptions.Compile)] on top of the class declaration.
I want to set VisibleProperty of BoxView as false for the last element of list which is defined in a viewcell containing stacklayout (grid+boxview). Is there any way to make it false so that last element wont contain boxview separator line?
Solution:
You can add a bool property isShow to your viewModel and use this property to control whether the boxView is visible or not.
public class MyViewModel
{
//use this property to control whether the boxView is visible
public bool isShow { get; set; }
}
And then binding this property to the boxView in your customCell By boxOne.SetBinding(BoxView.IsVisibleProperty, new Binding("isShow")):
public CustomCell()
{
//instantiate each of our views
var grid = new Grid();
var horizontalLayout = grid;
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
var boxOne = new BoxView { BackgroundColor = Color.Purple };
var boxTwo = new BoxView { BackgroundColor = Color.AliceBlue };
grid.Children.Add(boxOne, 0, 0);
grid.Children.Add(boxTwo, 1, 1);
//Binding here
boxOne.SetBinding(BoxView.IsVisibleProperty, new Binding("isShow"));
View = horizontalLayout;
}
At last , when you creating a new instance of MyViewModel, you can set the isShow property true/false to control whether the boxView is visible in your cell.
public MainViewCode()
{
myCollection = new ObservableCollection<MyViewModel>();
ListView lstView = new ListView();
lstView.ItemTemplate = new DataTemplate(typeof(CustomCell));
myCollection.Add(new MyViewModel { isShow = true });
myCollection.Add(new MyViewModel { isShow = false });
lstView.ItemsSource = myCollection;
Content = lstView;
}
I am trying to populate a listview with a customcell I made. I know how to do it with a tableview, but i have no idea how to do it with a listview. Can someone explain to me please, thank you
Excuse the very rough snippet of code but it is merely to explain the concept behind listviews and databinding.
In my example below I create a listview, assign a custom viewCell and bind the view cell to a model. The model data is populated by XML data retrieved from the server(Code emitted for simplicity). Simpler implementations can be done should you require a listview with hardcoded data.
I suggest reading through the http://developer.xamarin.com/guides/cross-platform/xamarin-forms/introduction-to-xamarin-forms/ and researching the MVVM principle
Additionally the best example code I have found to go through is an enlightening application written by James Montemagno https://github.com/jamesmontemagno/Hanselman.Forms
public TestPage()
{
private ListView listView; // Create a private property with the Type of Listview named listview
listView = new ListView(); //Instantiate the listview
var viewTemplate = new DataTemplate(typeof(CustomViewCell)); //Create a variable for the custom data template
listView.ItemTemplate = viewTemplate; // set the data template to the variable created above
this.Content = new StackLayout()
{
Children = {
listView
}
};
}
Custom View Cell:
public class CustomViewCell : ViewCell
{
public CustomViewCell()
{
Label Test = new Label()
{
Font = Font.BoldSystemFontOfSize(17),
TextColor = Helpers.Color.AppGreen.ToFormsColor(),
BackgroundColor = Color.White
};
var image = new Image();
image.Source = ImageSource.FromFile("testing.png");
Label Test2 = new Label();
tour_Desc.SetBinding(Label.TextProperty, "Test");
round_Desc.SetBinding(Label.TextProperty, "Test2");
var grid = new Grid
{
VerticalOptions = LayoutOptions.FillAndExpand,
RowDefinitions =
{
new RowDefinition {Height = GridLength.Auto },
new RowDefinition {Height = GridLength.Auto },
new RowDefinition {Height = 1}
},
ColumnDefinitions =
{
new ColumnDefinition {Width = GridLength.Auto},
new ColumnDefinition {Width = new GridLength(1, GridUnitType.Star)},
new ColumnDefinition {Width = 80 }
}
,BackgroundColor = Color.White,
};
grid.Children.Add(image, 0, 0);
Grid.SetRowSpan(image, 2);
grid.Children.Add(tour_Desc, 1, 0);
Grid.SetColumnSpan(tour_Desc, 2);
grid.Children.Add(Test, 1, 1);
grid.Children.Add(Test2, 1, 2);
this.View = grid;
}
}
View Model:
public partial class GamesResult
{
public string Test { get; set; }
public string Test1 { get; set; }
}