obtener entrada de texto desde la ventana wpf

Estoy usando un evento key_up en mi ventana para agregar los datos escritos a un generador de cadenas.

<Grid x:Name="grdMain" KeyUp="grdMain_KeyUp">
        <Grid.RowDefinitions>...

    private StringBuilder buffer = new StringBuilder();
    private void Window_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.Key != Key.Enter)
        {
            buffer.Append(e.Key);
        }

el caso es que los datos aplicados al búfer son "NumPad4" en lugar de "4" y "D3" en lugar de "3"... ¿me estoy perdiendo algo? ¿Hay alguna manera de agregar los datos como si estuvieran escritos en un cuadro de texto? Sé que puedo convertir los datos yo mismo, pero parece extraño que no haya una forma integrada de hacerlo.

preguntado el 03 de mayo de 12 a las 11:05

bueno, no es extraño que el contenedor de diseño no tenga un evento TextChanged, no tiene texto. Lo raro es lo que estás haciendo. ¿Por qué necesita Grid para recibir texto? -

en realidad es una petición del cliente. no quiere preocuparse por dónde está el foco. -

2 Respuestas

Podrías usar TextCompositionManager.TextInput Evento adjunto.

<Grid x:Name="grdMain"
      TextCompositionManager.TextInput="grid_TextInput">

In TextCompositionEventArgsTextCompositionEventArgs encontrarás lo que buscas.

private void grid_TextInput(object sender, TextCompositionEventArgs e)
{
    MessageBox.Show(e.Text);
}

contestado el 03 de mayo de 12 a las 12:05

Ok, esto puede parecer extraño a primera vista, pero creo que es la forma correcta de hacerlo. derivé de un TextBox y agregado ContentPresenter allí para alojar cualquier contenido y el Content propiedad para establecer ese contenido.

Por lo tanto, cree un control personalizado de WPF (es una plantilla de Visual Studio) llamado TextBoxContainer. añádele la siguiente propiedad:

    #region Content (DependencyProperty)

    /// <summary>
    /// Gets or sets Content property
    /// </summary>
    public object Content
    {
        get { return (object)GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }
    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register("Content", typeof(object), typeof(TextBoxContainer),
          new PropertyMetadata(null));

    #endregion

Reemplace su estilo en el archivo Assets/generic.xaml con lo siguiente:

<LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0">
    <GradientStop Color="#ABADB3" Offset="0.05"/>
    <GradientStop Color="#E2E3EA" Offset="0.07"/>
    <GradientStop Color="#E3E9EF" Offset="1"/>
</LinearGradientBrush>
<Style TargetType="{x:Type local:TextBoxContainer}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
    <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Padding" Value="1"/>
    <Setter Property="AllowDrop" Value="true"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
    <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TextBoxContainer}">
                <Grid>
                    <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
                        <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Microsoft_Windows_Themes:ListBoxChrome>
                    <ContentPresenter Content="{TemplateBinding Content}"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Y úsalo como sigue:

<local:TextBoxContainer TextChanged="TextBoxGrid_TextChanged" >
    <local:TextBoxContainer.Content>
        <Grid>
            <!-- Any markup here -->
        </Grid>
    </local:TextBoxContainer.Content>
</local:TextBoxContainer>

Tenga en cuenta que en cualquier momento tiene texto que contiene todo el texto que se ingresó. Lo único que debe tener en cuenta es que algunos elementos evitan que surjan algunos eventos. Por ejemplo TextBox se detiene KeyDown evento burbujeante. Así que si colocas TextBox dentro TextBoxContainer y el usuario hará clic en él y comenzará a ingresar texto allí: TextBoxContainer no recibirá ese texto, aunque se activará TextChanged evento.

contestado el 03 de mayo de 12 a las 12:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.