有没有办法在WPF的TextBox中添加固定的文本(TextBlock或Label)?这样;用户可以在控件中围绕它编写文本,但是不能删除或编辑它吗?
我正在寻找this question的倒数,即:
<TextBox>
"Chunk #1: This part of text is editable"
"Chunk #2: This piece is not editable"
"Chunk #3: This text is editable"
</TextBox>
(注意:这些是用于详细说明的虚构卡盘,它是一个文本块的所有延续;它可能是带有换行符的多行。)
Chunk #2
应相应移动的位置,用户可以修改Chunk #1
和#3
。
答案 0 :(得分:4)
您可以在StackPanel中使用三个TextBox控件:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1">
<TextBox BorderThickness="1,1,0,1"/>
<TextBox BorderThickness="0,1,0,1"
Text="Chunk 2" IsReadOnly="True"
IsTabStop="False" />
<TextBox BorderThickness="0,1,1,1"/>
</StackPanel>
</Grid>
结果如下:
编辑:您应该能够使用Tab键从第一个TextBox跳转到最后一个TextBox。
答案 1 :(得分:1)
我可能认为屏蔽文本框是可能的解决方案。在wpftoolkit中查看有关如何使用它的codeplex上的this article。
答案 2 :(得分:1)
如果您希望UI的行为类似于单个TextBox,则可能需要自定义TextBox控件。
在尝试各种活动后,我提出了以下解决方案:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WpfApplication1
{
public class MyTextBox : TextBox
{
public MyTextBox()
{
TextChanged += new TextChangedEventHandler(MyTextBox_TextChanged);
PreviewKeyDown += new KeyEventHandler(MyTextBox_PreviewKeyDown);
PreviewTextInput += new TextCompositionEventHandler(MyTextBox_PreviewTextInput);
DataObject.AddPastingHandler(this, new DataObjectPastingEventHandler(OnPaste));
}
private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
if (!IsValidPositionForEdit())
{
e.CancelCommand(); // do not allow pasting
}
}
void MyTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
if (!IsValidPositionForEdit())
{
e.Handled = true;
}
}
void MyTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (!IsValidPositionForEdit())
{
e.Handled = true;
}
}
private bool IsValidPositionForEdit()
{
return SelectionStart <= this.before || SelectionStart >= this.before + ReadOnlyTextChunk.Length;
}
public static readonly DependencyProperty ReadOnlyTextChunkProperty = DependencyProperty.Register(
"ReadOnlyTextChunk", typeof(string), typeof(MyTextBox), new PropertyMetadata(""));
public string ReadOnlyTextChunk
{
get { return (string)GetValue(ReadOnlyTextChunkProperty); }
set { SetValue(ReadOnlyTextChunkProperty, value); }
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Text = ReadOnlyTextChunk;
this.before = 0;
this.after = ReadOnlyTextChunk.Length;
}
void MyTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
foreach (TextChange ch in e.Changes)
{
if (ch.Offset <= this.before) // before text was modified
{
this.before += ch.AddedLength - ch.RemovedLength;
}
else if (ch.Offset >= this.before + ReadOnlyTextChunk.Length) // after text was modified
{
this.after += ch.AddedLength - ch.RemovedLength;
}
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Tab) // jump to after part
{
if (SelectionStart <= this.before)
{
SelectionStart = this.before + ReadOnlyTextChunk.Length;
e.Handled = true;
}
else
{
base.OnKeyDown(e);
}
}
}
private int before; // length of before part
private int after; // length of after part
}
}
按如下方式使用:
<local:MyTextBox ReadOnlyTextChunk="Chunk2" TextWrapping="Wrap" Width="200" Height="50"/>
结果如下所示: