【问题标题】:Silverlight - how to call a command based upon a property wihtin the viewSilverlight - 如何根据视图中的属性调用命令
【发布时间】:2011-06-01 18:25:19
【问题描述】:

我已经在这个问题上敲了几个小时,我希望有人能指出我正确的方向。

我的视图中有一个按钮,它有一个点击事件和一个附加的命令。 click 事件根据当前状态将网格行的可见性设置为折叠或可见。

xaml

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="120" />
        <RowDefinition x:Name="DetailHolder" Height="*" />
    </Grid.RowDefinitions>
    <Grid x:Name="LayoutRoot">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="92.915" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Button x:Name="DetailButton"
                Grid.Column="1"
                Width="107"
                Height="23"
                Margin="196,94,0,0"
                HorizontalAlignment="Left"
                VerticalAlignment="Top"
                Click= "MoreDetail_Click"
                Command="{Binding GetCFSDetailCommand}"
                Content="View Details [+]" >
            <Button.DataContext>
                <mdc:SearchViewModel/>
            </Button.DataContext>
        </Button>
    </Grid>
    <Grid x:Name="MyDetail"
          Grid.Row="1"
          MinHeight="150"
          Visibility="Collapsed">
        <TextBlock Text="My Hidden Data" />
    </Grid>
</Grid>

点击命令调用一个方法来测试 MyDetail 部分的当前视觉状态并展开或折叠它

命令从我的 viewModel 等调用 GetCFSDetailCommand

我卡住的地方是我只想在视图折叠时调用命令 GetCFSDetailCommand。现在设置的方式是每次单击按钮时都会触发命令。我不能使用 ICommand CanExecute 因为我不想禁用该按钮。我将不胜感激有关如何实现这一目标的任何建议或想法。一种想法是测试背后的事件代码中的可见性,然后在此基础上让事件调用命令。如果这是正确的方法,我将非常感谢代码示例,因为我没有运气从事件中调用命令。

提前致谢

【问题讨论】:

    标签: silverlight mvvm icommand


    【解决方案1】:

    在 DataTrigger 中设置您的 Command 属性

    <Button x:Name="DetailButton" Content="View Details [+]">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=MyDetail, Path=Visibility}"
                                 Value="Collapsed">
                        <Setter Property="Command" Value="{Binding GetCFSDetailCommand}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    <Button>
    

    命令将在 MyDetail 面板折叠时设置。否则,它是不受约束的,什么都不会发生。

    【讨论】:

    • 非常聪明,从未考虑过使用数据触发器来设置 Command 属性,但在这种特殊情况下非常有意义。
    【解决方案2】:

    您可以使用指定ElementName 的绑定将CommandParameter 绑定到网格的可见性,然后根据传递给命令的参数值选择执行或不执行您的命令。

    CommandParameter="{Binding ElementName=MyDetail, Path=可见性}"

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="120" />
            <RowDefinition x:Name="DetailHolder" Height="*" />
        </Grid.RowDefinitions>
        <Grid x:Name="LayoutRoot">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="92.915" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Button x:Name="DetailButton" 
                    Grid.Column="1" Width="107" Height="23" Margin="196,94,0,0" 
                    HorizontalAlignment="Left" VerticalAlignment="Top" 
                    Command="{Binding GetCFSDetailCommand}" 
                    CommandParameter="{Binding ElementName=MyDetail, Path=Visibility}"
                    Content="View Details [+]"
            >
    
            </Button>
        </Grid>
        <Grid x:Name="MyDetail" Grid.Row="1" MinHeight="150" Visibility="Collapsed">
            <TextBlock Text="My Hidden Data" />
        </Grid>
    </Grid>
    

    您可能必须考虑源最初为 null,但我使用了上面的 XAML 并且能够将可见性传递给我的命令处理程序。

    【讨论】:

    • 你能举例说明 CommandParameter 如何指向 Visibility 属性吗?在阅读有关自绑定的信息时,目标元素被用作绑定到同一元素的另一个属性的源。按钮和网格是两个独立的元素..我看错了吗?看起来我需要使用 CommandParameter="{Binding Visibility, ElementName=MyDetail, Mode=TwoWay}"
    • 您是对的,ElementName 或 Source 可用于引用 Grid 及其可见性。我更新了我的答案以正确反映这一点。希望这会有所帮助。
    • 很酷,但我仍然想念您如何在视图模型中引用此参数。我一直在尝试将其传递给委托命令,但没有运气,即参数无法识别......有什么建议吗?
    • 我正在使用中继命令实现(视图模型中的命令将 CanExecute 和 OnExecute 委托给我的视图模型中的方法)。有关示例,请参见 msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030
    【解决方案3】:

    从事件中调用命令是合法的,您也可以直接从 XAML 中执行此操作。您也可以将可见性状态作为命令参数传递。

    请参阅下面的示例:

    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
    
    <Rectangle Fill="White"
               Stroke="Black"
               Width="200"
               Height="100">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseEnter">
                <cmd:EventToCommand Command="{Binding TestCommand,
                                              Mode=OneWay}"
                   CommandParameter="{Binding Text,
                                      ElementName=MyTextBox,
                                      Mode=OneWay}"
                   MustToggleIsEnabledValue="True" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Rectangle>
    

    您将为此使用 MvvmLight 工具包。您可以通过 NuGet 轻松安装它。

    来源:MvvmLight

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-20
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多