如何在不使用事件的情况下从用户控件中检索输入

时间:2015-03-11 20:31:17

标签: wpf vb.net user-controls

我有一个非常不寻常的情况。我需要在表单上显示用户控件以获取用户输入。但我不想尝试通过事件检索信息。原因是它将我的代码拆分为三种不同的方法,我想尝试防止这种情况。如果有办法,我可以做到这一点,那将是非常棒的。

我尝试过使用byRef变量但因为它们都在UI线程中,我的UserControl没有显示出来。

提前谢谢

窗口

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:me="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel >
        <Button Name="btnTest" Click="btnTest_Click" Content="Click Me!" />
        <Button Name="btnTest2" Click="btnTest2_Click" Content="Click Me Too!" />
    </StackPanel>

    <me:ucInputBox x:Name="Input" Visibility="Collapsed" />
</Grid>

用户控制

<UserControl x:Class="ucInputBox"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" x:Name="InputBox">
<UserControl.Resources>
    <Style TargetType="{x:Type Button}">
        <Setter Property="Cursor" Value="Hand"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border x:Name="Border" Background="{TemplateBinding Background}" CornerRadius="4" BorderThickness="2">
                        <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="Border" Property="Background" Value="#ECECEC" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="Border" Property="Background" Value="#CECECE" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter TargetName="Border" Property="Opacity" Value="0.7" />
                            <Setter Property="Foreground" Value="Gray"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
<Grid >
    <Grid Background="Black" Opacity="0.5"/>
    <Border
        MinWidth="250"
        Background="WhiteSmoke" 
        BorderBrush="Black" 
        BorderThickness="1" 
        HorizontalAlignment="Center" 
        VerticalAlignment="Center">
        <StackPanel >
            <TextBlock Name="txbInput" Margin="10" Text="Input Box:" FontWeight="Bold" FontFamily="Cambria" />
            <TextBox MinWidth="150" HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="InputTextBox" Width="210" TextWrapping="WrapWithOverflow" />
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,5,0,0">
                <Button x:Name="OKButton" Content="Ok" Margin="5" Click="OKButton_Click" IsDefault="True" Height="30" Width="50"/>
                <Button x:Name="CancelButton" Content="Cancel" Margin="5" Click="CancelButton_Click" IsCancel="True" Height="30" Width="50" />
            </StackPanel>
        </StackPanel>
    </Border>
</Grid>

代码背后

Class MainWindow 
#Region " Split Method"
Private Sub btnTest_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
    '\\\\\\\\\ Button using split method
    Input.Visibility = Windows.Visibility.Visible
End Sub

Private Sub Input_Submit(Response As String) Handles Input.Submit
    '\\\\\\\ since this is the event all code that depends on the input goes here.
    '\\\\\\\ If Multiple methods need input this blows up
End Sub
#End Region


Private Sub btnTest2_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
    Input.HandledLocally = True
    '\\\\\\\\\ This method gets stuck and never shows becuase the while loop is in the UI thread
    Dim holder = Input.GetInput()

End Sub
End Class

用户控制背后的代码

Public Class ucInputBox
Public Event Submit(ByVal Response As String)

Private _TextBoxString As String
Public Property TextBoxString() As String
    Get
        Return _TextBoxString
    End Get
    Set(ByVal value As String)
        _TextBoxString = value
        txbInput.Text = _TextBoxString
    End Set
End Property

Private _WaitingForInput As Boolean = True
Public Property WaitingForInput() As Boolean
    Get
        Return _WaitingForInput
    End Get
    Set(ByVal value As Boolean)
        _WaitingForInput = value
    End Set
End Property

Private _HandledLocally As Boolean
Public Property HandledLocally() As Boolean
    Get
        Return _HandledLocally
    End Get
    Set(ByVal value As Boolean)
        _HandledLocally = value
    End Set
End Property

Public Function GetInput() As String
    InputBox.Visibility = Windows.Visibility.Visible
    While Not WaitingForInput
        '\\\\\\ Wait for input
    End While
    Dim ret As String
    ret = InputTextBox.Text
    InputTextBox.Text = String.Empty
    Return ret
End Function

Private Sub CancelButton_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
    InputBox.Visibility = Windows.Visibility.Collapsed
    InputTextBox.Text = String.Empty
    If HandledLocally Then
        WaitingForInput = False
    Else
        RaiseEvent Submit(String.Empty)
    End If


End Sub

Private Sub OKButton_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
    InputBox.Visibility = Windows.Visibility.Collapsed
    If HandledLocally Then
        WaitingForInput = False
    Else
        RaiseEvent Submit(String.Empty)
        InputTextBox.Text = String.Empty
    End If
    'RaiseEvent Submit(String.Empty)
    'InputTextBox.Text = String.Empty
End Sub

Private Sub UserControl_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    txbInput.Text = _TextBoxString
    InputTextBox.Focus()
    OKButton.IsEnabled = False
End Sub

Private Sub InputTextBox_TextChanged(sender As System.Object, e As System.Windows.Controls.TextChangedEventArgs) Handles InputTextBox.TextChanged
    If InputTextBox.Text.Trim <> String.Empty Then
        OKButton.IsEnabled = True
    Else
        OKButton.IsEnabled = False
    End If
End Sub
End Class

0 个答案:

没有答案