WPF标签到文本框

时间:2010-12-08 02:09:43

标签: c# wpf

我在WPF中非常棒,但是我非常认真地试图掌握它:p

我一直在尝试创建一个控件,其中显示一个标签/文本块,但是一旦用户悬停/点击控件,就会显示一个文本框,以便可以编辑该值。

我一直在尝试将Visible属性绑定到代码隐藏中的布尔值,该布尔值使用MouseOver和MouseLeave以及Got / LostFocus的委托更新,但它不起作用。此外,我尝试使用一个简单的样式,也将Visible属性绑定到代码隐藏中的布尔值...也没有工作。最后,我按照WPF: Label to TextBox when selected的建议,使用ControlTemplate和Trigger,如下所示:

    <Style x:Key="TransformerBox" TargetType="{x:Type TextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter Property="Visibility" Value="Visible"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Canvas x:Name="CnvCantidad" Grid.Row="2" Grid.Column="1">
        <TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="16" Canvas.Top="8" Width="16" 
                 x:Name="TxtCantidad" Style="{StaticResource TransformerBox}" Height="23" Visibility="Visible"/>
        <Label HorizontalAlignment="Center" VerticalAlignment="Center" Content="0" Canvas.Left="16" Canvas.Top="6" 
               x:Name="LblCantidad"/>
    </Canvas>

但在之前解释过的所有案例中,无论如何都无法看到TextBox:/

我应该如何创建ControlTemplate,以便在用户悬停Label / TextBlock时可以看到TextBox?

4 个答案:

答案 0 :(得分:7)

当IsMouseOver为True时,编辑一个标签的样式以使TextBox出现。这比两个可重用性控制更好。

<Style x:Key="EditableLabelStyle" TargetType="{x:Type Label}">
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Padding" Value="5"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalContentAlignment" Value="Top"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Label}">
                <Grid>
                    <TextBox Name="textBox"
                             Grid.ZIndex="1"
                             Padding="1,3,0,0"
                             Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Label}}, Path=Content, UpdateSourceTrigger=PropertyChanged}"
                             Opacity="0"/>
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="textBox" Property="Opacity" Value="1"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

像这样使用

<Label Style="{StaticResource EditableLabelStyle}" HorizontalAlignment="Center" VerticalAlignment="Center" Content="0" Canvas.Left="16" Canvas.Top="6"  
       x:Name="LblCantidad"/>

答案 1 :(得分:0)

有几种方法可以做到这一点。

这是一种方式,它只是使TextBox隐藏,直到您将鼠标悬停在Label或TextBox上(否则当TextBox出现时鼠标不再悬停在Label上)。您可能需要对其进行调整,但您应该明白这一点(请注意,它实际上并不隐藏Label,只是在其上显示TextBox):

<Canvas x:Name="CnvCantidad" Grid.Row="2" Grid.Column="1">
        <Label HorizontalAlignment="Center" VerticalAlignment="Center" Content="0" Canvas.Left="16" Canvas.Top="6" 
           x:Name="LblCantidad"/>
        <TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="16" Canvas.Top="8" Width="16" 
             x:Name="TxtCantidad" Height="23">
            <TextBox.Style>
                <Style TargetType="{x:Type TextBox}">
                    <Setter Property="Visibility" Value="Collapsed" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=LblCantidad, Path=IsMouseOver}" Value="True">
                            <Setter Property="Visibility" Value="Visible" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding ElementName=TxtCantidad, Path=IsMouseOver}" Value="True">
                            <Setter Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>
    </Canvas>

答案 2 :(得分:0)

如果您正在处理布尔值和可见性,则应考虑使用ValueConverter

这是一个关于如何绑定到模型中的布尔值(IsTextVisible)并将其映射到可见性折叠或可见的示例。

<强> XAML:

 <TextBox HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="16" 
  Canvas.Top="8" Width="16" 
  x:Name="TxtCantidad" Style="{StaticResource TransformerBox}" Height="23" 
  Visibility="{Binding IsTextVisible, 
               Converter={StaticResource BoolToVisibilityConverter}}"/>

ValueConverter代码:

public class BoolToVisibilityConverter : IValueConverter
{
    object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool isVisible = Convert.ToBoolean(value);

        return isVisible ? Visibility.Visible : Visibility.Collapsed;
    }

    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

此外,您还必须在XAML中导入转换器命名空间

xmlns:converter="clr-namespace:Foo.Converter"

并为其指定一个密钥

<converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>

修改

如果您为了您的目的直接绑定到后面的代码,您可以这样在XAML中为Window设置DataContext

 DataContext="{Binding RelativeSource={RelativeSource Self}}"

还要确保绑定到属性

public bool IsTextVisible {get;set;}

从长远来看,您需要查看以下主题:

  1. Data Binding in WPF
  2. MVVM in WPF

答案 3 :(得分:0)

您可以通过在触发器中设置ContentTemplate,或者将文本框设置为资源并使用触发器设置它来执行此操作。检查此示例

<Label Height="30" BorderBrush="Gray" BorderThickness="1">
    <Label.Resources>
        <TextBox x:Key="ContenTextBoxt" HorizontalAlignment="Stretch"/>
    </Label.Resources>
    <Label.Style>
        <Style TargetType="{x:Type Label}">
            <Setter Property="Padding"
                                    Value="0" />
                <Setter Property="HorizontalContentAlignment"
                                    Value="Stretch" />
                <Setter Property="VerticalContentAlignment"
                                    Value="Stretch" />
                <Setter Property="Content"
                                    Value="No mouse over" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver"
                                             Value="True">
                    <Setter Property="Content" Value="{StaticResource ContenTextBoxt}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Label.Style>
    </Label>