[英]Pass value UserControl to ViewModel of View Page
這是完整的示例代碼
使用MVVM模式我的要求是要有一個ListView
True
False
播放,並且ListView綁定值應在數據庫中更新。 如果為true,則應使用動畫彈出刻度線;如果為false,則應使用動畫隱藏刻度線。 現在,我為數據模板創建了用戶控件。 在這里,我想分別單擊checkbox
或單擊Item
來標識兩個事件。
使用ICommand
我正在創建兩個委托,它們被綁定到兩個透明按鈕上,以中繼輕擊事件。
創建透明按鈕和綁定綁定時創建代理的依賴性使我確信,肯定有一種更好的方式可以將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代碼背后
MainPageModel sampleItem { get { return this.DataContext as MainPageModel; } }
public MainPageUserControl()
{
this.InitializeComponent();
this.DataContextChanged += (s, e) => this.Bindings.Update();
}
視圖模型代碼
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);
}
主頁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>
必須有一種更好的方法來使用后面的代碼來獲得所需的結果。
項目中每個項目的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);
}
}
}
這是完整的演示: 演示項目
更新:
使用DelegateCommand
,可以將命令屬性添加到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 =“ True”,否則將不會觸發事件處理程序。
對於利用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>
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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.