繁体   English   中英

将值UserControl传递给视图页面的ViewModel

[英]Pass value UserControl to ViewModel of View Page

这是完整的示例代码
使用MVVM模式我的要求是要有一个ListView

  1. 如果用户在复选框“ 故事板”上的ListView内部点击,则True False播放,并且ListView绑定值应在数据库中更新。 如果为true,则应使用动画弹出刻度线;如果为false,则应使用动画隐藏刻度线。
    解决按@Elvis夏答案
  2. 如果用户点击ListviewItem导航到具有值的新页面
  3. 蓝图

现在,我为数据模板创建了用户控件。 在这里,我想分别单击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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM