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