我在Windows 8.1 C#app中尝试了以下内容:
<!-- XAML file -->
<Page.BottomAppBar>
<CommandBar>
<AppBarButton Label="Add News Feed" Icon="Add">
<AppBarButton.Flyout>
<Flyout>
<StackPanel Width="400">
<TextBlock TextWrapping="Wrap" Text="Enter Text:" Margin="0,0,0,10"/>
<TextBox x:Name="inputTextBox"/>
<Button Content="Add" HorizontalAlignment="Right" VerticalAlignment="Stretch" Click="AddButton_Click"/>
</StackPanel>
</Flyout>
</AppBarButton.Flyout>
</AppBarButton>
</CommandBar>
</Page.BottomAppBar>
// C# file
private void AddButon_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
var text = inputTextBox.Text;
// Do something with the text
}
但是,当我运行我的应用程序并单击“添加”按钮时,我得到一个System.NullReferenceException,因为成员inputTextBox为null。我检查过,生成的InitializeComponent方法有以下几行:
inputTextBox = (global::Windows.UI.Xaml.Controls.TextBox)this.FindName("inputTextBox");
我甚至尝试更改我的事件处理程序以调用FindName,以防在显示Flyout时创建控件并且它仍然返回null。为什么FindName找不到我的文本框?
更新:解决方法
我能够使用VisualTreeHelper访问TextBox,如下所示:
TextBox textBox = null;
var parent = VisualTreeHelper.GetParent(sender as Button);
var numChildren = VisualTreeHelper.GetChildrenCount(parent);
for (var i = 0; i < numChildren; ++i)
{
var child = VisualTreeHelper.GetChild(parent, i) as FrameworkElement;
if (child != null && child.Name == "inputTextBox")
{
// Found the text box!
textBox = child as TextBox;
break;
}
}
if (textBox != null)
{
var text = textBox.Text;
// Do something with the text
}
如果确实将此确认为Windows 8.1预览中的错误,我将继续关闭此问题。
答案 0 :(得分:1)
这是8.1预览版的一个问题,我们希望在最终版本的8.1
中解决此问题乔
答案 1 :(得分:1)
如果您不想使用VisualTreeHelper方法,您可以创建Flyout的子类,并使用Flyoutbase.SetAttachedFlyout(UIElement,FlyoutSubclass)将其附加到您的UI元素;
class ForgotPasswordFlyout : Flyout
{
StackPanel contentPanel = new StackPanel();
public Thickness margins = new Thickness(0, 0, 0, 10);
public Button forgotPasswordButton;
public ProgressBar forgotPasswordProgressBar;
public TextBlock forgotPasswordMessageTextBlock;
public TextBox forgotPasswordTextBox;
public ForgotPasswordFlyout()
{
forgotPasswordMessageTextBlock = new TextBlock();
forgotPasswordMessageTextBlock.Text = "Enter the email address you used to register.";
forgotPasswordMessageTextBlock.Margin = margins;
contentPanel.Children.Add(forgotPasswordMessageTextBlock);
forgotPasswordTextBox = new TextBox();
forgotPasswordTextBox.PlaceholderText = "Email";
forgotPasswordTextBox.Margin = margins;
contentPanel.Children.Add(forgotPasswordTextBox);
forgotPasswordButton = new Button();
forgotPasswordButton.Content = "Recover Password";
contentPanel.Children.Add(forgotPasswordButton);
forgotPasswordProgressBar = new ProgressBar();
forgotPasswordProgressBar.IsIndeterminate = true;
forgotPasswordProgressBar.Visibility = Visibility.Collapsed;
contentPanel.Children.Add(forgotPasswordProgressBar);
this.Content = contentPanel;
}
}
现在,我们无法直接访问文本框,因为x:名称不起作用。但是,在视图控制器中,我们可以为这些UI元素注册事件。
private void RecoverPasswordCommandButton_Click(object sender, RoutedEventArgs e)
{
ForgotPasswordFlyout forgotPassFlyout = new ForgotPasswordFlyout();
forgotPassFlyout.forgotPasswordTextBox.TextChanged += forgotPasswordTextBox_TextChanged;
forgotPassFlyout.forgotPasswordButton.Click += forgotPasswordFlyoutButton_Click;
FlyoutBase.SetAttachedFlyout(RecoverPasswordCommandButton, forgotPassFlyout);
FlyoutBase.ShowAttachedFlyout(RecoverPasswordCommandButton);
}
这样我们可以在事件触发时直接访问文本框并保存文本以供使用。
void forgotPasswordTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox forgotPasswordTextBox = sender as TextBox;
ForgotPasswordFlyout.forgotPasswordEmail = forgotPasswordTextBox.Text;
}