There is bindable Item source of Flexlayout
<FlexLayout x:Name="playerscollection" Wrap="Wrap" BindableLayout.ItemsSource="{Binding Players}" />
Items in the viewmodel are defined as
public ObservableCollection<PlayerModel> Players { get; set; }
FlexLayout datatemplate is a content view
I need to assign a specific viewmodel "PlayerViewModel" as the content view BindingContext
public PlayerViewModel(bool showPicker = true, PlayerModel player = null){}
So in FlexLayout,
<FlexLayout x:Name="playerscollection" Wrap="Wrap" BindableLayout.ItemsSource="{Binding Players}">
<views:PlayerView >
<views:PlayerView.BindingContext>
<viewModels:PlayerViewModel>
<x:Arguments>
<x:Boolean>False</x:Boolean>
<models:PlayerModel/>
</x:Arguments>
</viewModels:PlayerViewModel>
</views:PlayerView.BindingContext>
</views:PlayerView>
</FlexLayout>
But the error says "Type 'PlayerViewModel' is not usable as an object element because it is not public or does not define a public parameterless constructor or a type converter"
I've created a basic demo to test the code and reproduce the error. The error doesn't affect the project build, it's just an intellisense error of the IDE. Please ignore the error and deploy the code, it'll work fine.
Related
In WPF you can create a DataTemplate, put it in a ResourceDictionary, assign it a Type and then bind data of that type to a ContentControl and the DataTemplate will be used to render. as in this example:
How do I use the DataType property on a WPF DataTemplate?
the Xamarin.Forms enterprise apps ebook hints at such an ability but does not show any example: https://developer.xamarin.com/guides/xamarin-forms/enterprise-application-patterns/mvvm/#Creating_a_View_Defined_as_a_Data_Template
Can this be done in Xamarin.Forms?
Unfortunately, x:DataType does not working with Xamarin Forms.
(I tried many different ways, but fail.)
You should implement DataTemplateSelector
ResourceDictionary.xaml
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:forms="clr-namespace:Solution.Forms"
x:Class="Mango.Forms.LayerDataTemplate">
<!--#region RectLayerView -->
<DataTemplate x:Key="RectLayerDataTemplate">
<forms:RectLayerView forms:ValueX="{Binding ValueX}"
forms:ValueY="{Binding ValueY}"
forms:ValueWidth="{Binding ValueWidth}"
forms:ValueHeight="{Binding ValueHeight}"
forms:MangoColor="{Binding Color}" />
</DataTemplate>
<!--#endregion-->
<forms:LayerDataTemplateSelector x:Key="LayerDataTemplateSelector"
RectLayerTemplate="{StaticResource RectLayerDataTemplate}"/>
</ResourceDictionary>
DataTemplateSelector.cs
public class LayerDataTemplateSelector : DataTemplateSelector
{
public DataTemplate RectLayerTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
if (item is RectLayerViewModel)
return RectLayerTemplate;
return null;
}
}
Here is Microsoft document
I have 2 DataTemplates for displaying the contents of ClassA or ClassB inside a single ListView; which template to select will be based on a RadioButton selection by the user.
Is it possible to change the ItemTemplate of a ListView (in XAML) based on user input dynamically at runtime?
An example snippet of code:
XAML Page:
<Page...>
<Page.Resources>
<DataTemplate x:Key="ClassAListViewItemTemplate" x:DataType="vm:ClassA" ... />
<DataTemplate x:Key="ClassBListViewItemTemplate" x:DataType="vm:ClassB" ... />
</Page.Resources>
<RelativePanel>
<RadioButton Content="ClassA" ... />
<RadioButton Content="ClassB" ... />
<ListView DataContext="{Binding Path=MainViewModel}"
ItemsSource="{Binding ListOfClassAOrB, Mode=TwoWay}"
ItemTemplate="{StaticResource ClassAListViewItemTemplate}"/>
</RelativePanel>
</Page>
I have stripped the code down somewhat to the essentials, but I would like to be able to change the following at runtime:
ItemTemplate="{StaticResource ClassAListViewItemTemplate}"
I have seen solutions for Classic WPF applications that use Style.Triggers, but these aren't applicable for UWP
Marco Minerva's blog on Adaptive Triggers, RelativePanel and DataTemplate in the Universal Windows Platform talks of using UserControls within DataTemplates to modify the visual state using Adaptive Triggers, but this doesn't take into account switching out of templates based on user input
The closest answer I have found to my problem is another blog he wrote "Dynamically choose DataTemplate in WinRT" where there is an element of code-behind involved - but it only appears to be an if statement - but its the cleanest solution I have come across thus far, and what I'd like to replicate in XAML
Thanks
you need to use overwrite SelectTemplateCore of Data template. Change your view model like this.
Below code will helps you.
public class SampleViewModel : DataTemplateSelector
{
public DataTemplate ClassAListViewItemTemplate{ get; set; }
public DataTemplate ClassBListViewItemTemplate{ get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var itemsData = item as SampleClass; // add your Data class
if (itemsData.IsAddButton == false) // define any property to select the datatemplate
{
return ClassAListViewItemTemplate;
}
else
{
return ClassBListViewItemTemplate;
}
}
}
Add your two datatemplates to one key, and give the key to ItemTemplateSelector property in gridview.
<viewModels:SampleViewModel x:Key="FeedbackTempateSelector"
ClassAListViewItemTemplate="{StaticResource ClassAListViewItemTemplate}"
ClassBListViewItemTemplate="{StaticResource ClassBListViewItemTemplate}">
</viewModels:SampleViewModel>
I have a Windows 8.1 application. I have a requirement of selecting different templates based on a certain value. For this purpose I'm using ContentPresenter in the xaml with a Static Resource TemplateSelector.
Here's my datatemplates and templateselector in xaml resources
<DataTemplate x:Key="template1">
<TextBox Text="Temp 1" />
</DataTemplate>
<DataTemplate x:Key="template2">
<TextBox Text="Temp 2" />
</DataTemplate>
<DataTemplate x:Key="template3">
<TextBox Text="Temp 3" />
</DataTemplate>
<template:BalanceTypesTemplateSelector x:Key="MySelector"
Template1="{StaticResource template1}"
Template2="{StaticResource template2}"
Template3="{StaticResource template3}" />
Here's my ContentPresenter XAML
<ContentPresenter ContentTemplateSelector="{StaticResource MySelector}"
Content="{Binding MyData}" />
Here's my Template Selector Code
public class BalanceTypesTemplateSelector : DataTemplateSelector
{
public DataTemplate Template1 { get; set; }
public DataTemplate Template2 { get; set; }
public DataTemplate Template3 { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
var type = item.ToString();
switch (type)
{
case "t1":
return Template1;
case "t2":
return Template1;
case "t3":
return Template3;
default:
throw new NotSupportedException();
}
}
return null;
}
}
But it's not hitting the templateselector code at all. The string that is bound is directly displayed on the display when I run the app.
I would be glad if some one point me in the right direction. Thanks in Advance.
Basically, you're only overriding one of the SelectTemplateCore overloads.
From the DataTemplateSelector docs:
To define an effective DataTemplateSelector subclass, provide implementations for SelectTemplateCore(Object) and SelectTemplateCore(Object, DependencyObject)
Once you provide an implementation for SelectTemplateCore(Object, DependencyObject), it will get invoked.
I tried to do it, but there was another problem I encountered - the object is always null (and not the Content/DataContext of the ContentPresenter).
I asked Google why is that and found this discussion. From it:
The ContentControl and ContentPresenter appear to be broken in Windows RT when used with a ContentTemplateSelector property bound to a view model. The 'object' parameter to the template selector is always null.
There's also a workaround for this problem at the end of that discussion.
Hope this helps. :)
Using ContentControl instead of ContentPresenter is working for me. Thanks #KaiBrummund for his comment on my question.
I'm trying to figure out the RepeaterView in Xamarin Forms Labs.
THE BACKGROUND
I have a simple entity called Entry that has property called Notes
class Entry
{
public string Notes { get; set; }
}
In the common PCL, I've inherited from the RepeaterView to make it non-generic.
class EntryRepeater : Xamarin.Forms.Labs.Controls.RepeaterView<MyKids.Core.Entities.Entry>
{
}
And the XAML of the page where I'm trying to use the repeater looks like this
<rep:EntryRepeater ItemsSource="{Binding Entries}">
<rep:EntryRepeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout>
<Label Text="{Binding Notes}" />
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</rep:EntryRepeater.ItemTemplate>
</rep:EntryRepeater >
where Entries is an ObservableCollection.
THE ISSUE
The problem is that the binding in the DataTemplate seems to point to the main model and not to one item in the collection. BUT it is repeated the correct number of times.
[0:] Binding: 'Notes' property not found on 'MyApp.ViewModels.EntryListViewModel', target property: 'Xamarin.Forms.Label.Text'
To circle back to this question, this was actually an error in earlier versions of Xlabs. It's now fixed and the code above does work.
Hi guys I am working with SL4 and MVVM application actually i am stuck some where i might be doing some thing wrong thats why need your help, here is my scenario
//suodo code
public class EmployeeModel
{
//code
Public List<Shifts> Employeeshifts{get;set;}
}
public class ShiftModel
{
//code
}
Viewmodel for main page
public class MainVM
{
MainVM()
{
EmployeeList = DateFromSomeService;
}
Public List<Employees> EmployeeList{get;set}
Public DelegateCommand ClickBindingCommand{get;set;}
}
MainPage.xaml
<ItemsControl ItemSource={Binding EmployeeList}>
<ItemTemplate>
<DataTemplate>
<controls:EmployeeControl/>
</DataTemplate>
</ItemTemplate>
</ItemsControl>
Employeecontro.xaml
<ItemsControl ItemSource={Binding EmployeeShifts}>
<ItemTemplate>
<DataTemplate>
<controls:ShiftControl Click={Binding ClickBindingCommand}/>//here is problem this command is in mainviewmodel
</DataTemplate>
</ItemTemplate>
</ItemsControl>
MainPage.cs
this.DataContext = new MainVM();
ClickBindingCommand is defined in main VM but it is bound within shift control and shiftcontrol's data context is shift class which is my model class. If I declare this command in my shift model class than it works, means if I click on shift control this property is called but I dont want this because I want it in my main view model, where am I wrong?
Should I declare it in my shift model class but in this way i will bind directly my model to my view?
Use a DataContextProxy or a RelativeSource Binding. This will allow your Command to bind/fire on your MainViewModel.
Another alternative is to use the Caliburn Micro framework. You can then attach an action to your button in the child and click events will bubble up to the parent.
This "toolkit" offers an implementation of FindAncestor in silverlight. Try this:
http://blog.thekieners.com/2010/09/08/relativesource-binding-with-findancestor-mode-in-silverlight/
I ran into this same issue and what fixed it for me was to name my UserControl then reference that name in the binding.
Here is the syntax:
{Binding ElementName=SomeTextBox, Path=Text}
Bind to the “Text” property of the element XAML
element with name=”SomeTextBox” or x:Name=”SomeTextBox”.
So here is my user control:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SupportReports.Workflow.Portfolio.PortfolioManager"
mc:Ignorable="d"
Name="PortfolioManagerControl"
>
And here is the nested dataTemplate that binds to my command in my main view model
<cmd:EventToCommand Command="{Binding ElementName=PortfolioManagerControl, Path=DataContext.PortfolioManagerProjectSelectedCommand}" CommandParameter="{Binding Text, ElementName=ProjectName}" />