我在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?
答案 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;}
从长远来看,您需要查看以下主题:
答案 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>