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;
}
Related
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;
}
}
}
I'm using ReactiveUI and trying to get a CollectionView to use a ReactiveContentPage as it's item template in code behind. This works okay until the ReactiveContentView is nested under another Element.
The problem I have is that after scrolling the collection view, the items get duplicated. After debugging, it would seem that the ReactiveContentView's BindingContext or ViewModel aren't updated.
The samples below have been simplified to highlight the issue:
This doesn't work:
public partial class SampleCollectionPage : ReactiveContentPage<SampleCollectionViewModel>
{
private void Build()
{
Content = new CollectionView
{
ItemTemplate = new DataTemplate(() =>
{
return new ContentView
{
Content = new ReactiveContentView<CollectionItemViewModel>
{
Content = new StackLayout
{
Children =
{
new Label()
.Bind(Label.TextProperty, nameof(CollectionItemViewModel.Title)),
new Label()
.Bind(Label.TextProperty, nameof(CollectionItemViewModel.Description)),
new Label()
.Bind(Label.TextProperty, nameof(CollectionItemViewModel.SomeTime)),
}
}
}
};
}),
}
.Bind(CollectionView.ItemsSourceProperty, path: nameof(SampleCollectionViewModel.Items));
}
}
This works:
public partial class SampleCollectionPage : ReactiveContentPage<SampleCollectionViewModel>
{
private void Build()
{
Content = new CollectionView
{
ItemTemplate = new DataTemplate(() =>
{
return new ReactiveContentView<CollectionItemViewModel>
{
Content = new StackLayout
{
Children =
{
new Label()
.Bind(Label.TextProperty, nameof(CollectionItemViewModel.Title)),
new Label()
.Bind(Label.TextProperty, nameof(CollectionItemViewModel.Description)),
new Label()
.Bind(Label.TextProperty, nameof(CollectionItemViewModel.SomeTime)),
}
}
};
}),
}
.Bind(CollectionView.ItemsSourceProperty, path: nameof(SampleCollectionViewModel.Items));
}
}
The only difference being that the working version doesn't put the ReactiveContentView in a ContentView. I'm not sure if I'm missing something or whether this is an bug in Xamarin Forms or ReactiveUI?
(edited to add actual problem: doh)
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 need to hide some view, when listview scrolled up and display that view again, when list view scrolled down.
I used
private void ScheduleServiceList_ItemAppearing(object sender, Xamarin.Forms.ItemVisibilityEventArgs e)
{
var currentItem = e.Item as VehicleService;
double listviewheight = ScheduleServiceListView.Height;
if (viewModel.VehicleServiceList[0].Id == currentItem.Id)
{
SearchEntryLayout.IsVisible = true;
HeadingGrid.Margin = new Thickness(0, -70, 0, 0);
}
}
What about:
var listView = new ListView(ListViewCachingStrategy.RecycleElement)
{
....
ItemTemplate = new DataTemplate(() =>
{
return new MyListViewCellView(new List<int> { ... /* ids to disable or other objects */ });
})
};
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; }
}