How to exit out of method and return control back to user and not the calling method?
I have a listview and a button next to it that uses the selected item to do an action. If the user doesn't make a selection, but clicks on the button they are told to make a selection first.
What I have below works, but is there a way where the calling method doesn't have to have the "if(not selected)" return statement? I want to just call "selectionFound()" method from other events that rely on the listview? I'd like the selectionFound method to exit out of not just its开发者_如何学JAVAelf, but also the calling method and return control back to the user. So instead of return true/false as below, I'd like to have just return or whatever keyword.
private void deleteData()
{
// if nothing selected, warn user and return control
if(!selectionFound()) return;
.....
}
private bool selectionFound()
{
// make sure user selected an item from listview, warn and exit if not
if (lvwInventory.SelectedIndex == -1)
{
MessageBox.Show("Please select an item first");
return false;
}
else
return true;
}
Aside from returning a flag as per your example, the closest you're going to get is to throw an exception, as that's the only mechanism I'm aware of that can jump entire stack frames without letting methods finish executing.
EDIT: And you should not use exceptions for this purpose, since they indicate that something exceptional happened.
Why even put this in code? In the xaml you can disable the button if an item isn't selected.
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<ListView x:Name="listy">
<ListViewItem>one
</ListViewItem>
<ListViewItem>two
</ListViewItem>
<ListViewItem>three
</ListViewItem>
</ListView>
<Button Grid.Row="1" Content="Clicky">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedItem, ElementName=listy}" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
The selectionFound() method would not have any practical way to keep deleteData from continuing execution after it returns; the way you have done it is how it must be done.
Another answer mentions Exceptions; I strongly recommend against that. Your example does not seem to me to be appropriate for an exception - and an exception would not technically do what you want; the calling method could catch the exception (meaning it's still up to the calling method how it acts)
I don't think what you are asking for is possible without tweaks... The only thing that comes to my mind is to wrap the rest of the deleteData method in a delegate and pass it to the selectionFound method as a parameter. But that would only mess up the code .
I think you're trying to "second-guess" the framework with your selectionfound()
method there. I'd re-factor what you have to the following:
private void deleteData()
{
// if nothing selected, warn user and return control
if(lvwInventory.SelectedIndex == -1)
{
MessageBox.Show("Please select an item first");
return;
}
// Rest of function below...
}
The SelectedIndex
property is already doing for you (more or less) what your selectionfound()
method was doing. Just detect and display in your deleteData() method, and just do return
there as you want to.
The only reason not to do it this way IMO is if you are doing this from 5 different places, and always want the same dialog, or whatever. Then for less code duplication, you need the return code, as you had before.
You could use the listView changed event to enable the other controls. Have your button be disabled by default, enable it when the listView changed event reveals the user has something selected. Personally, I'd still check for a value, but you could be reasonably sure that one exists if you made it to your button click event.
And in case it's not obvious what I'm getting at, you could eliminate the check for foundSelection() from your button click handler.
精彩评论