Silverlight - how to call a command based upon a property wihtin the view
I have been banging my head on this one for hours and I am hoping someone can point me in the correct direction.
I have a button within my view which has a click event and a command attached. The click event sets the visibility of a grid row to collapsed or visible based upon the current state.
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>
The click command calls a method that tests the current visual state of the MyDetail section and expands or collapses it
The Command calls GetCFSDetailCommand from my viewModel etc
Where I am stuck is that I only want to call the Command GetCFSDetailCommand when the view is collapsed. The way it is set now is that command will fire every time the button is clicked. I can't use ICommand CanExecute because I don't want to disable the button. I'd appreciate any suggestions or ideas on how to go about achieving this. One thought was to test the visibility within the event code behind and then based upon that have the event call the Command. If this is the correct approach I would rea开发者_JAVA技巧lly appreciate a code sample as I have had no luck in calling the command from an event.
Thanks in advance
Set your Command property in a DataTrigger
<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>
The Command will be set when the MyDetail panel is collapsed. Otherwise, it is unbound and nothing will happen.
You could bind the CommandParameter to the Visibility of your grid using a binding that specifies the ElementName, and then choose to execute or not execute your command based on the value of the parameter passed to the command.
CommandParameter="{Binding ElementName=MyDetail, Path=Visibility}"
<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>
You may have to account for the source being null initially, but I used the XAML above and was able to pass the visibility to my command handler.
It is legit to call a command from an event and you can do it right from your XAML too. You can pass in the visibility state as a command parameter as well.
See the sample below:
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>
You'll the MvvmLight toolkit for this. You can easily install it through NuGet.
Source: MvvmLight
精彩评论