我有一个textBox样式。我在其中更改了带有附加矩形的textBox控件模板。我希望矩形的宽度绑定到已键入的文本的宽度。
这是当前的风格
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBoxBase}">
<Border Name="Border"
Padding="2"
Background="{DynamicResource White#}">
<StackPanel VerticalAlignment="Center">
<ScrollViewer Margin="0" x:Name="PART_ContentHost" />
<Rectangle x:Name="Rect1" Width="{Binding ActualWidth, ElementName=PART_ContentHost}" Height="2" Fill="{TemplateBinding Foreground}" Opacity="0.8">
<Rectangle.LayoutTransform>
<ScaleTransform ScaleX="0" />
</Rectangle.LayoutTransform>
</Rectangle>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
这个xaml栏延伸我希望它只是与文本
一样宽我需要在控件模板的setter中添加什么以及绑定必须是什么?
答案 0 :(得分:2)
你非常接近。
首先,我将ScrollViewer
添加到ScaleTransform
,以防止它扩展到其父级的全宽。
其次,我删除了将Rectangle缩小到零水平大小的<StackPanel VerticalAlignment="Center" >
<ScrollViewer
Margin="0"
x:Name="PART_ContentHost"
HorizontalAlignment="Left"
/>
<Rectangle
x:Name="Rect1"
Width="{Binding ActualWidth, ElementName=PART_ContentHost}"
Height="2"
Fill="{TemplateBinding Foreground}" Opacity="0.8"
HorizontalAlignment="Left"
>
</Rectangle>
</StackPanel>
。
ScrollViewer
现在你还有另外一个问题:用户必须在using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
namespace MyRandomNamespace
{
public static class Extensions
{
#region Extensions.MouseDownFocusRecipient Attached Property
// Attached property. See XAML example below for usage.
// On mouse down, sets focus on bound target control.
public static UIElement GetMouseDownFocusRecipient(UIElement obj)
{
return (UIElement)obj.GetValue(MouseDownFocusRecipientProperty);
}
public static void SetMouseDownFocusRecipient(UIElement obj, UIElement value)
{
obj.SetValue(MouseDownFocusRecipientProperty, value);
}
public static readonly DependencyProperty MouseDownFocusRecipientProperty =
DependencyProperty.RegisterAttached("MouseDownFocusRecipient", typeof(UIElement), typeof(Extensions),
new PropertyMetadata(null, MouseDownFocusRecipient_PropertyChanged));
private static void MouseDownFocusRecipient_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = d as UIElement;
// Target must have some kind of background color or it will ignore mouse events.
// We can't do this object-orientedly because multiple Background dependency
// properties are defined in multiple control classes.
var bkgDepProp = DependencyPropertyDescriptor.FromName("Background", target.GetType(), target.GetType(), true);
if (bkgDepProp != null && bkgDepProp.GetValue(target) == null)
{
bkgDepProp.SetValue(target, System.Windows.Media.Brushes.Transparent);
}
//target.IsHitTestVisible = true;
target.PreviewMouseDown -= Target_PreviewMouseDown;
target.PreviewMouseDown += Target_PreviewMouseDown;
}
private static void Target_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var target = (UIElement)sender;
var otherControl = GetMouseDownFocusRecipient(target);
if (otherControl != null)
{
Keyboard.Focus(otherControl);
}
}
#endregion Extensions.MouseDownFocusRecipient Attached Property
}
}
内点击以使其获得焦点,这样他才能开始输入,而滚动查看器则是一个挤在控件左侧的小东西。我正在寻找一些方法来做到这一点;等待更新。
如何处理mousedown而不对MVVM提出任何错误:
<ControlTemplate TargetType="{x:Type TextBoxBase}" x:Key="TextBoxTemplate">
<Border
Name="Border"
Padding="2"
Background="{DynamicResource White#}"
local:Extensions.MouseDownFocusRecipient="{Binding ElementName=PART_ContentHost}"
>
<StackPanel
VerticalAlignment="Center"
MouseDown="StackPanel_MouseDown"
>
<ScrollViewer
Margin="0"
x:Name="PART_ContentHost"
HorizontalAlignment="Left"
/>
<Rectangle
x:Name="Rect1"
Width="{Binding ActualWidth, ElementName=PART_ContentHost}"
Height="8"
Fill="{TemplateBinding Foreground}" Opacity="0.8"
IsHitTestVisible="False"
HorizontalAlignment="Left"
/>
</StackPanel>
</Border>
</ControlTemplate>
XAML:
target
答案 1 :(得分:1)
所以Ed更好。我甚至没有考虑只处理焦点并让ScrollViewer的ActualWidth提供值。我想更多地沉浸在实际测量ScrollViewer中的Text Element作为逻辑子元素,这在我看来会更加复杂。除了他的方式工作。然而,我也遇到了一个问题,因为严格的要求只允许XAML而没有代码隐藏来完成同样的事情。除了它是一个单实例表单输入,允许这个快速黑客。
我会亲自与Ed一起去,但提交作为一个快速的替代方案,你可以做这样的事情,并只是背负值,以使ActualWidth脱离另一个元素。它不优雅,但很简单......
PoC xaml;
Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="theText"
Text="{Binding Text, ElementName=theBox, UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Left" Opacity="0"/>
<TextBox x:Name="theBox"
Height="30" Width="250" MaxLength="50"/>
<Rectangle Grid.Row="1" Fill="Green"
Width="{Binding ActualWidth, ElementName=theText}"
HorizontalAlignment="Left" Height="25"/>
</Grid>
干杯!