这是完整的Sample code
使用 MVVM 模式我的要求是将ListView置于其中
True
False
播放,并且应该在数据库中更新ListView绑定值。如果为true,则勾选应弹出动画为false,勾选应该变为动画不可见。 现在我使用了usercontrol创建datatemplate。在这里,我想分别用户点击checkbox
或单独点击Item
来识别这两个事件。
使用ICommand
我创建了两个代表,它们绑定到两个透明按钮继电器轻拍事件。在创建透明按钮和创建delgates时依赖于绑定它们让我觉得必须有更好的方法可以在没有任何代码的情况下利用 MVVM 来完成这些事件
UserControl XAML
<Button Background="LightBlue" BorderBrush="White" BorderThickness="4" Command="{x:Bind sampleItem.itemTapped}" CommandParameter="{Binding}" HorizontalContentAlignment="Stretch">
<Grid Margin="20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Margin="20" HorizontalAlignment="Center" Text="{x:Bind sampleItem.sampleText}" FontSize="30"/>
<Image Grid.Column="1" Height="60" Width="60" Source="ms-appx:///Assets/check_off.png" HorizontalAlignment="Right"/>
<Image x:Name="image" Grid.Column="1" Height="60" Width="60" Source="ms-appx:///Assets/check_on.png" HorizontalAlignment="Right" Visibility="Collapsed" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<CompositeTransform/>
</Image.RenderTransform>
</Image>
<Button x:Name="btnFav" Grid.Column="1" Height="60" Width="60" HorizontalAlignment="Right" Background="Transparent" Command="{x:Bind sampleItem.favTapped}" CommandParameter="{Binding}">
<Interactivity:Interaction.Behaviors>
<!--<Core:EventTriggerBehavior EventName="Tapped">
<Core:InvokeCommandAction Command="{Binding favTapped}" />
</Core:EventTriggerBehavior>-->
<Core:DataTriggerBehavior Binding="{Binding isFav}" Value="true">
<Media:ControlStoryboardAction Storyboard="{StaticResource StoryboardCheckOn}"/>
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{Binding isFav}" Value="false">
<Media:ControlStoryboardAction Storyboard="{StaticResource StoryboardCheckOff}"/>
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
</Grid>
</Button>
UserControl XAML codeBehind
MainPageModel sampleItem { get { return this.DataContext as MainPageModel; } }
public MainPageUserControl()
{
this.InitializeComponent();
this.DataContextChanged += (s, e) => this.Bindings.Update();
}
Viewmodel代码
public async Task GetData()
{
for (int i = 0; i < 10; i++)
{
if (i == 3)
sampleList.Add(new MainPageModel { sampleText = "Selected", isFav = true, favTapped= new DelegateCommand<MainPageModel>(this.OnFavTapped), itemTapped= new DelegateCommand<MainPageModel>(this.OnItemTapped)});
else
sampleList.Add(new MainPageModel { sampleText = "UnSelected"+i.ToString(), isFav = null, favTapped = new DelegateCommand<MainPageModel>(this.OnFavTapped), itemTapped = new DelegateCommand<MainPageModel>(this.OnItemTapped) });
}
}
private void OnFavTapped(MainPageModel arg)
{
if (arg.isFav == null) arg.isFav = true;
else
arg.isFav = !arg.isFav;
}
private void OnItemTapped(MainPageModel arg)
{
System.Diagnostics.Debug.WriteLine("Button Value: "+arg.sampleText);
System.Diagnostics.Debug.WriteLine("Selected Item Value: "+selectedItem.sampleText);
}
MainPage Xaml
<Grid Grid.Row="1">
<ListView ItemsSource="{x:Bind ViewModel.sampleList}" IsItemClickEnabled="True" SelectedItem="{Binding ViewModel.selectedItem,Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<userControls:MainPageUserControl/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
使用背后的代码必须有更好的方法来实现所需的结果。
答案 0 :(得分:1)
项目中每个项目的DataContext都是MainPageModel
类的实例。所以favTapped命令应该添加到MainPageModel
类。它是一个命令,所以favTapped应该是一个新类的实例,它实现ICommand
接口。
如果您不想在首次加载页面时显示动画,则可以将isFav
设置为bool?
。当页面首次加载时,将isFav的值设置为null,从而不会触发动画操作。
以下是代码段和演示链接:
ViewModelCommands.cs:
public class ViewModelCommands : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
//if it's a tapped event
if (parameter is TappedRoutedEventArgs)
{
var tappedEvent = (TappedRoutedEventArgs)parameter;
var gridSource = (Grid)tappedEvent.OriginalSource;
var dataContext = (MainPageModel)gridSource.DataContext;
//if tick is true then set to false, or the opposite.
if (dataContext.isFav == null)
{
dataContext.isFav = true;
} else
{
dataContext.isFav = !dataContext.isFav;
}
}
}
}
MainPageModel.cs:
public class MainPageModel:BindableBase
{
public MainPageModel() {
favTapped = new ViewModelCommands();
}
public ViewModelCommands favTapped { get; set; }
private string _sampleText;
public string sampleText
{
get
{
return this._sampleText;
}
set
{
Set(ref _sampleText, value);
}
}
private bool? _isFav;
public bool? isFav
{
get
{
return this._isFav;
}
set
{
Set(ref _isFav, value);
}
}
}
以下是完整的演示:Demo Project
<强>更新强>
使用DelegateCommand
时,可以将命令Property添加到MainPageModel.cs,因为项目的DataContext是MainPageModel实例。您可以使用this.isFav
更改点击项目的isFav
值。
以下是MainPageModel.cs的代码:
public class MainPageModel : BindableBase
{
private DelegateCommand _favTapped;
public DelegateCommand favTapped
{
get
{
if (_favTapped == null)
{
_favTapped = new DelegateCommand(() =>
{
//Here implements the check on or off logic
this.CheckOnOff();
}, () => true);
}
return _favTapped;
}
set { _favTapped = value; }
}
private void CheckOnOff()
{
if (this.isFav == null)
{
this.isFav = true;
}
else
{
this.isFav = !this.isFav;
}
}
private string _sampleText;
public string sampleText
{
get
{
return this._sampleText;
}
set
{
Set(ref _sampleText, value);
}
}
private bool? _isFav;
public bool? isFav
{
get
{
return this._isFav;
}
set
{
Set(ref _isFav, value);
}
}
}
对于Listview项目选择
您可以使用ListView.ItemClick事件。但你也应该设置IsItemClickEnabled =&#34; True&#34;否则事件处理程序不会被解雇。
对于Listview的子项目点击
您可以使用userControl的Tapped Event。
以下是Xaml代码,显示了如何注册以上两个事件:
<Grid Grid.Row="1">
<ListView IsItemClickEnabled="True" ItemClick="ListView_ItemClick_1" ItemsSource="{x:Bind ViewModel.sampleList}">
<ListView.ItemTemplate>
<DataTemplate>
<userControls:MainPageUserControl Tapped="MainPageUserControl_Tapped"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
答案 1 :(得分:1)
public class ViewMOdel()
{
public ViewModel()
{
favTapped= new DelegateCommand<MainPageModel>(this.OnFavTapped)
itemTapped= new DelegateCommand<MainPageModel>(this.OnItemTapped)
}
public async Task GetData()
{
for (int i = 0; i < 10; i++)
{
if (i == 3)
sampleList.Add(new MainPageModel { sampleText = "Selected", isFav = true});
else
sampleList.Add(new MainPageModel { sampleText = "UnSelected"+i.ToString(), isFav = null});
}
}
private void OnFavTapped(MainPageModel arg)
{
if (arg.isFav == null) arg.isFav = true;
else
arg.isFav = !arg.isFav;
}
private void OnItemTapped(MainPageModel arg)
{
System.Diagnostics.Debug.WriteLine("Button Value: "+arg.sampleText);
System.Diagnostics.Debug.WriteLine("Selected Item Value: "+selectedItem.sampleText);
}
}
绑定应该是这样的
<Button x:Name="btnFav" Grid.Column="1" Height="60" Width="60" HorizontalAlignment="Right" Background="Transparent" Command="{Binding ElementName=UserControl, Path=Tag.favTapped}" CommandParameter="{Binding}"/>
<强>更新强>
<ListView ItemsSource="{x:Bind ViewModel.sampleList}" x:Name="Listview"IsItemClickEnabled="True" SelectedItem="{Binding ViewModel.selectedItem,Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<userControls:MainPageUserControl Tag="{Binding DataContext,ElementName=Listview}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button x:Name="btnFav" Grid.Column="1" Height="60" Width="60" HorizontalAlignment="Right" Background="Transparent" Command="{Binding ElementName=UserControl, Path=Tag.favTapped}" CommandParameter="{Binding}"/>
使用EventTriggerBehavior Update2
favTapped = new DelegateCommand<RoutedEventArgs>(this.OnFavTapped);
private void OnFavTapped(RoutedEventArgs arg)
{
var item = (( arg.OriginalSource )as Button).DataContext as MainPageModel
}
<Button n x:Name="btnFav" Grid.Column="1" Height="60" Width="60" HorizontalAlignment="Right" Background="Transparent" >
<interact:Interaction.Behaviors>
<interactcore:EventTriggerBehavior EventName="Click" >
<interactcore:InvokeCommandAction Command="{Binding ElementName=usercontrol, Path=Tag.favTapped}" />
</interactcore:EventTriggerBehavior>
</interact:Interaction.Behaviors>
</Button>