Adding different Commands to elements in dynamically populated ListView
I have a ListView with dynamically added items. Every row in the list contains a Label, a Switch and a Button. The respective Button should only be visible when the Switch for that ViewCell is toggled. The respective Button should also have a Command that is specific to that item in the list. How can I achieve this? I am using the MVVM pattern.
<ListView HorizontalOptions="FillAndExpand" ItemsSource="{Binding SomeList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label
HorizontalOptions="StartAndExpand"
Text="{Binding SomePropertyFromSomeList}"
VerticalOptions="Center" />
<Switch />
<Button
Command="{Binding DoSomethingSpecificToThisSwitch}"
IsVisible="{Binding VisibleWhenThisSwitchIsToggled}"
Text="{Binding AlsoDependentOnWhichSwitch}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
c# xaml xamarin.forms
add a comment |
I have a ListView with dynamically added items. Every row in the list contains a Label, a Switch and a Button. The respective Button should only be visible when the Switch for that ViewCell is toggled. The respective Button should also have a Command that is specific to that item in the list. How can I achieve this? I am using the MVVM pattern.
<ListView HorizontalOptions="FillAndExpand" ItemsSource="{Binding SomeList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label
HorizontalOptions="StartAndExpand"
Text="{Binding SomePropertyFromSomeList}"
VerticalOptions="Center" />
<Switch />
<Button
Command="{Binding DoSomethingSpecificToThisSwitch}"
IsVisible="{Binding VisibleWhenThisSwitchIsToggled}"
Text="{Binding AlsoDependentOnWhichSwitch}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
c# xaml xamarin.forms
add a comment |
I have a ListView with dynamically added items. Every row in the list contains a Label, a Switch and a Button. The respective Button should only be visible when the Switch for that ViewCell is toggled. The respective Button should also have a Command that is specific to that item in the list. How can I achieve this? I am using the MVVM pattern.
<ListView HorizontalOptions="FillAndExpand" ItemsSource="{Binding SomeList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label
HorizontalOptions="StartAndExpand"
Text="{Binding SomePropertyFromSomeList}"
VerticalOptions="Center" />
<Switch />
<Button
Command="{Binding DoSomethingSpecificToThisSwitch}"
IsVisible="{Binding VisibleWhenThisSwitchIsToggled}"
Text="{Binding AlsoDependentOnWhichSwitch}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
c# xaml xamarin.forms
I have a ListView with dynamically added items. Every row in the list contains a Label, a Switch and a Button. The respective Button should only be visible when the Switch for that ViewCell is toggled. The respective Button should also have a Command that is specific to that item in the list. How can I achieve this? I am using the MVVM pattern.
<ListView HorizontalOptions="FillAndExpand" ItemsSource="{Binding SomeList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label
HorizontalOptions="StartAndExpand"
Text="{Binding SomePropertyFromSomeList}"
VerticalOptions="Center" />
<Switch />
<Button
Command="{Binding DoSomethingSpecificToThisSwitch}"
IsVisible="{Binding VisibleWhenThisSwitchIsToggled}"
Text="{Binding AlsoDependentOnWhichSwitch}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
c# xaml xamarin.forms
c# xaml xamarin.forms
asked Nov 15 '18 at 8:15
ZebrastianZebrastian
536
536
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Best way I find to tackle this, is to use a CommandParameter
and decide what to do in your ViewModel
based on the context of the ViewCell
data.
If you use Binding, you can bind to the whole context of the current data by selecting a . ( dot ), that way the data from the current ViewCell is passed to your ViewModel.
Let's show how you code this...
Your View should look like this
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestCommand"
x:Name="TestPage"
x:Class="TestCommand.MainPage">
<StackLayout>
<ListView ItemsSource="{Binding Persons}" RowHeight="50">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Name}" />
<Button Text="Click" Command="{Binding DoCommand, Source={x:Reference TestPage}}" CommandParameter="{Binding .}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Note that you need to provide a Name for your page! With that you can point to the same command in each ViewCell. But pass in the current ViewCell data with the Command Parameter.
In your ViewModel you than can act upon the 'selected' data... and do something specific like so:
public List<Person> Persons { get; set; } = new List<Person>() { new Person() { Name = "Glenn Versweyveld" }, new Person() { Name = "John Do" } };
private Command<Person> _doCommand;
public Command<Person> DoCommand => _doCommand ?? (_doCommand = new Command<Person>((Person obj) => HandlePerson(obj)));
private void HandlePerson(Person obj)
{
}
I'm trying to test your example, but I can't get the DoCommand binding to work. I get "Binding: 'DoCommand' property not found on 'TestCommand.MainPage', target property: 'Xamarin.Forms.Button.Command'". Do you have any idea what I'm missing?
– Zebrastian
Nov 15 '18 at 10:39
What is the BindingContext of your ContentPage?
– Depechie
Nov 15 '18 at 10:42
The error code at least, means that it's looking for the Command in the BindingContext of the ContentPage. But that that BindingContext ( your ViewModel ) does not contain the DoCommand public property.
– Depechie
Nov 15 '18 at 10:48
My MainPage.xaml.cs should do the BindingContext: this.BindingContext = new TestViewModel();
– Zebrastian
Nov 15 '18 at 11:22
That seems correct and you added the command on that TestViewModel I guess... now the error you posted states "not found on 'TestCommand.MainPage', target property". Did you just copy paste my code over your ContentPage code? Because I think the ClassName should be your test page class name and not the one I provided in this sample...
– Depechie
Nov 15 '18 at 11:40
|
show 3 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53314994%2fadding-different-commands-to-elements-in-dynamically-populated-listview%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Best way I find to tackle this, is to use a CommandParameter
and decide what to do in your ViewModel
based on the context of the ViewCell
data.
If you use Binding, you can bind to the whole context of the current data by selecting a . ( dot ), that way the data from the current ViewCell is passed to your ViewModel.
Let's show how you code this...
Your View should look like this
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestCommand"
x:Name="TestPage"
x:Class="TestCommand.MainPage">
<StackLayout>
<ListView ItemsSource="{Binding Persons}" RowHeight="50">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Name}" />
<Button Text="Click" Command="{Binding DoCommand, Source={x:Reference TestPage}}" CommandParameter="{Binding .}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Note that you need to provide a Name for your page! With that you can point to the same command in each ViewCell. But pass in the current ViewCell data with the Command Parameter.
In your ViewModel you than can act upon the 'selected' data... and do something specific like so:
public List<Person> Persons { get; set; } = new List<Person>() { new Person() { Name = "Glenn Versweyveld" }, new Person() { Name = "John Do" } };
private Command<Person> _doCommand;
public Command<Person> DoCommand => _doCommand ?? (_doCommand = new Command<Person>((Person obj) => HandlePerson(obj)));
private void HandlePerson(Person obj)
{
}
I'm trying to test your example, but I can't get the DoCommand binding to work. I get "Binding: 'DoCommand' property not found on 'TestCommand.MainPage', target property: 'Xamarin.Forms.Button.Command'". Do you have any idea what I'm missing?
– Zebrastian
Nov 15 '18 at 10:39
What is the BindingContext of your ContentPage?
– Depechie
Nov 15 '18 at 10:42
The error code at least, means that it's looking for the Command in the BindingContext of the ContentPage. But that that BindingContext ( your ViewModel ) does not contain the DoCommand public property.
– Depechie
Nov 15 '18 at 10:48
My MainPage.xaml.cs should do the BindingContext: this.BindingContext = new TestViewModel();
– Zebrastian
Nov 15 '18 at 11:22
That seems correct and you added the command on that TestViewModel I guess... now the error you posted states "not found on 'TestCommand.MainPage', target property". Did you just copy paste my code over your ContentPage code? Because I think the ClassName should be your test page class name and not the one I provided in this sample...
– Depechie
Nov 15 '18 at 11:40
|
show 3 more comments
Best way I find to tackle this, is to use a CommandParameter
and decide what to do in your ViewModel
based on the context of the ViewCell
data.
If you use Binding, you can bind to the whole context of the current data by selecting a . ( dot ), that way the data from the current ViewCell is passed to your ViewModel.
Let's show how you code this...
Your View should look like this
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestCommand"
x:Name="TestPage"
x:Class="TestCommand.MainPage">
<StackLayout>
<ListView ItemsSource="{Binding Persons}" RowHeight="50">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Name}" />
<Button Text="Click" Command="{Binding DoCommand, Source={x:Reference TestPage}}" CommandParameter="{Binding .}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Note that you need to provide a Name for your page! With that you can point to the same command in each ViewCell. But pass in the current ViewCell data with the Command Parameter.
In your ViewModel you than can act upon the 'selected' data... and do something specific like so:
public List<Person> Persons { get; set; } = new List<Person>() { new Person() { Name = "Glenn Versweyveld" }, new Person() { Name = "John Do" } };
private Command<Person> _doCommand;
public Command<Person> DoCommand => _doCommand ?? (_doCommand = new Command<Person>((Person obj) => HandlePerson(obj)));
private void HandlePerson(Person obj)
{
}
I'm trying to test your example, but I can't get the DoCommand binding to work. I get "Binding: 'DoCommand' property not found on 'TestCommand.MainPage', target property: 'Xamarin.Forms.Button.Command'". Do you have any idea what I'm missing?
– Zebrastian
Nov 15 '18 at 10:39
What is the BindingContext of your ContentPage?
– Depechie
Nov 15 '18 at 10:42
The error code at least, means that it's looking for the Command in the BindingContext of the ContentPage. But that that BindingContext ( your ViewModel ) does not contain the DoCommand public property.
– Depechie
Nov 15 '18 at 10:48
My MainPage.xaml.cs should do the BindingContext: this.BindingContext = new TestViewModel();
– Zebrastian
Nov 15 '18 at 11:22
That seems correct and you added the command on that TestViewModel I guess... now the error you posted states "not found on 'TestCommand.MainPage', target property". Did you just copy paste my code over your ContentPage code? Because I think the ClassName should be your test page class name and not the one I provided in this sample...
– Depechie
Nov 15 '18 at 11:40
|
show 3 more comments
Best way I find to tackle this, is to use a CommandParameter
and decide what to do in your ViewModel
based on the context of the ViewCell
data.
If you use Binding, you can bind to the whole context of the current data by selecting a . ( dot ), that way the data from the current ViewCell is passed to your ViewModel.
Let's show how you code this...
Your View should look like this
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestCommand"
x:Name="TestPage"
x:Class="TestCommand.MainPage">
<StackLayout>
<ListView ItemsSource="{Binding Persons}" RowHeight="50">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Name}" />
<Button Text="Click" Command="{Binding DoCommand, Source={x:Reference TestPage}}" CommandParameter="{Binding .}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Note that you need to provide a Name for your page! With that you can point to the same command in each ViewCell. But pass in the current ViewCell data with the Command Parameter.
In your ViewModel you than can act upon the 'selected' data... and do something specific like so:
public List<Person> Persons { get; set; } = new List<Person>() { new Person() { Name = "Glenn Versweyveld" }, new Person() { Name = "John Do" } };
private Command<Person> _doCommand;
public Command<Person> DoCommand => _doCommand ?? (_doCommand = new Command<Person>((Person obj) => HandlePerson(obj)));
private void HandlePerson(Person obj)
{
}
Best way I find to tackle this, is to use a CommandParameter
and decide what to do in your ViewModel
based on the context of the ViewCell
data.
If you use Binding, you can bind to the whole context of the current data by selecting a . ( dot ), that way the data from the current ViewCell is passed to your ViewModel.
Let's show how you code this...
Your View should look like this
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TestCommand"
x:Name="TestPage"
x:Class="TestCommand.MainPage">
<StackLayout>
<ListView ItemsSource="{Binding Persons}" RowHeight="50">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Name}" />
<Button Text="Click" Command="{Binding DoCommand, Source={x:Reference TestPage}}" CommandParameter="{Binding .}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Note that you need to provide a Name for your page! With that you can point to the same command in each ViewCell. But pass in the current ViewCell data with the Command Parameter.
In your ViewModel you than can act upon the 'selected' data... and do something specific like so:
public List<Person> Persons { get; set; } = new List<Person>() { new Person() { Name = "Glenn Versweyveld" }, new Person() { Name = "John Do" } };
private Command<Person> _doCommand;
public Command<Person> DoCommand => _doCommand ?? (_doCommand = new Command<Person>((Person obj) => HandlePerson(obj)));
private void HandlePerson(Person obj)
{
}
answered Nov 15 '18 at 9:09
DepechieDepechie
5,1261939
5,1261939
I'm trying to test your example, but I can't get the DoCommand binding to work. I get "Binding: 'DoCommand' property not found on 'TestCommand.MainPage', target property: 'Xamarin.Forms.Button.Command'". Do you have any idea what I'm missing?
– Zebrastian
Nov 15 '18 at 10:39
What is the BindingContext of your ContentPage?
– Depechie
Nov 15 '18 at 10:42
The error code at least, means that it's looking for the Command in the BindingContext of the ContentPage. But that that BindingContext ( your ViewModel ) does not contain the DoCommand public property.
– Depechie
Nov 15 '18 at 10:48
My MainPage.xaml.cs should do the BindingContext: this.BindingContext = new TestViewModel();
– Zebrastian
Nov 15 '18 at 11:22
That seems correct and you added the command on that TestViewModel I guess... now the error you posted states "not found on 'TestCommand.MainPage', target property". Did you just copy paste my code over your ContentPage code? Because I think the ClassName should be your test page class name and not the one I provided in this sample...
– Depechie
Nov 15 '18 at 11:40
|
show 3 more comments
I'm trying to test your example, but I can't get the DoCommand binding to work. I get "Binding: 'DoCommand' property not found on 'TestCommand.MainPage', target property: 'Xamarin.Forms.Button.Command'". Do you have any idea what I'm missing?
– Zebrastian
Nov 15 '18 at 10:39
What is the BindingContext of your ContentPage?
– Depechie
Nov 15 '18 at 10:42
The error code at least, means that it's looking for the Command in the BindingContext of the ContentPage. But that that BindingContext ( your ViewModel ) does not contain the DoCommand public property.
– Depechie
Nov 15 '18 at 10:48
My MainPage.xaml.cs should do the BindingContext: this.BindingContext = new TestViewModel();
– Zebrastian
Nov 15 '18 at 11:22
That seems correct and you added the command on that TestViewModel I guess... now the error you posted states "not found on 'TestCommand.MainPage', target property". Did you just copy paste my code over your ContentPage code? Because I think the ClassName should be your test page class name and not the one I provided in this sample...
– Depechie
Nov 15 '18 at 11:40
I'm trying to test your example, but I can't get the DoCommand binding to work. I get "Binding: 'DoCommand' property not found on 'TestCommand.MainPage', target property: 'Xamarin.Forms.Button.Command'". Do you have any idea what I'm missing?
– Zebrastian
Nov 15 '18 at 10:39
I'm trying to test your example, but I can't get the DoCommand binding to work. I get "Binding: 'DoCommand' property not found on 'TestCommand.MainPage', target property: 'Xamarin.Forms.Button.Command'". Do you have any idea what I'm missing?
– Zebrastian
Nov 15 '18 at 10:39
What is the BindingContext of your ContentPage?
– Depechie
Nov 15 '18 at 10:42
What is the BindingContext of your ContentPage?
– Depechie
Nov 15 '18 at 10:42
The error code at least, means that it's looking for the Command in the BindingContext of the ContentPage. But that that BindingContext ( your ViewModel ) does not contain the DoCommand public property.
– Depechie
Nov 15 '18 at 10:48
The error code at least, means that it's looking for the Command in the BindingContext of the ContentPage. But that that BindingContext ( your ViewModel ) does not contain the DoCommand public property.
– Depechie
Nov 15 '18 at 10:48
My MainPage.xaml.cs should do the BindingContext: this.BindingContext = new TestViewModel();
– Zebrastian
Nov 15 '18 at 11:22
My MainPage.xaml.cs should do the BindingContext: this.BindingContext = new TestViewModel();
– Zebrastian
Nov 15 '18 at 11:22
That seems correct and you added the command on that TestViewModel I guess... now the error you posted states "not found on 'TestCommand.MainPage', target property". Did you just copy paste my code over your ContentPage code? Because I think the ClassName should be your test page class name and not the one I provided in this sample...
– Depechie
Nov 15 '18 at 11:40
That seems correct and you added the command on that TestViewModel I guess... now the error you posted states "not found on 'TestCommand.MainPage', target property". Did you just copy paste my code over your ContentPage code? Because I think the ClassName should be your test page class name and not the one I provided in this sample...
– Depechie
Nov 15 '18 at 11:40
|
show 3 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53314994%2fadding-different-commands-to-elements-in-dynamically-populated-listview%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown