- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用 UWP 中的普通 TextBox
,您可以数据绑定(bind)到 Text
属性,并轻松地从 ViewModel 获取或设置值。 RichEditBox
虽然没有可绑定(bind)数据的 Text
属性;相反,您必须使用 ITextDocument
interface由 Document
属性公开,并使用各种方法来获取和设置文本。
如何将纯文本数据绑定(bind)到我的 ViewModel 中的内容?
最佳答案
可以使用自定义 attached property 对 RichEditBox
的纯文本进行数据绑定(bind).此附加属性处理文档的富文本和纯文本之间的转换。
这是一个示例 XAML 页面、代码隐藏和显示附加属性用法的 ViewModel:
将此复制为项目中新页面的内容
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Margin="30">
<RichEditBox local:RichEditBoxExtension.PlainText="{Binding PlainText,
Mode=TwoWay}" x:Name="richedit"/>
<Button Content="Bold selection" Click="MakeBold"/>
<Button Content="Change plain text (view model)" Click="ChangeText"/>
<Button Content="Change rich text (control property)" Click="ChangeRichText"/>
<TextBlock Text="PlainText property is..." />
<TextBlock Text="{Binding PlainText, Mode=OneWay}" />
</StackPanel>
</Grid>
这假设您使用的是默认的 MainPage.xaml.cs
;适当更改构造函数名称
public MainPage()
{
InitializeComponent();
DataContext = model = new ViewModel();
model.PlainText = "Hello, world";
}
private void ChangeText(object sender, RoutedEventArgs e)
{
model.PlainText = "Here is some plain text";
}
private void ChangeRichText(object sender, RoutedEventArgs e)
{
richedit.Document.SetText(TextSetOptions.None, "Here is some rich text");
var selection = richedit.Document.Selection;
selection.StartPosition = 8;
selection.EndPosition = 12;
selection.CharacterFormat.Underline = UnderlineType.Single;
selection.MoveStart(TextRangeUnit.Word, 1);
selection.Expand(TextRangeUnit.Word);
selection.CharacterFormat.Weight = FontWeights.Bold.Weight;
}
private void MakeBold(object sender, RoutedEventArgs e)
{
richedit.Document.Selection.CharacterFormat.Weight = FontWeights.Bold.Weight;
}
没什么特别的;只是一个字符串属性。您可以将它放在自己的文件中,或将其粘贴到主代码隐藏文件中。
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string plainText;
public string PlainText
{
get { return plainText; }
set
{
plainText = value;
RaisePropertyChanged();
}
}
void RaisePropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
到目前为止,没有什么特别的。 RichEditBox
使用附加属性 RichEditBoxExtension.PlainText
并将其绑定(bind)到 ViewModel 属性 PlainText
。页面上还有另一个 TextBlock
用于显示 PlainText
属性的当前值,以及一些用于操作文本的按钮。
RichEditBoxExtension.PlainText
的实现非常简单,但由于依赖属性基础结构和需要避免无休止的属性更新(改变 rich文本触发纯文本,富文本触发富文本,富文本触发纯文本,依此类推。
这可以在它自己的文件中,也可以再次粘贴到代码隐藏文件中。
public class RichEditBoxExtension
{
// Standard attached property. It mimics the "Text" property of normal text boxes
public static readonly DependencyProperty PlainTextProperty =
DependencyProperty.RegisterAttached("PlainText", typeof(string),
typeof(RichEditBoxExtension), new PropertyMetadata(null, OnPlainTextChanged));
// Standard DP infrastructure
public static string GetPlainText(DependencyObject o)
{
return o.GetValue(PlainTextProperty) as string;
}
// Standard DP infrastructure
public static void SetPlainText(DependencyObject o, string s)
{
o.SetValue(PlainTextProperty, s);
}
private static void OnPlainTextChanged(DependencyObject o,
DependencyPropertyChangedEventArgs e)
{
var source = o as RichEditBox;
if (o == null || e.NewValue == null)
return;
// This attaches an event handler for the TextChange event in the RichEditBox,
// ensuring that we're made aware of any changes
AttachRichEditBoxChangingHelper(o);
// To avoid endless property updates, we make sure we only change the RichText's
// Document if the PlainText was modified (vs. if PlainText is responding to
// Document being modified)
var state = GetState(o);
switch (state)
{
case RichEditChangeState.Idle:
var text = e.NewValue as string;
SetState(o, RichEditChangeState.PlainTextChanged);
source.Document.SetText(Windows.UI.Text.TextSetOptions.None, text);
break;
case RichEditChangeState.RichTextChanged:
SetState(o, RichEditChangeState.Idle);
break;
default:
Debug.Assert(false, "Unknown state");
SetState(o, RichEditChangeState.Idle);
break;
}
}
#region Glue
// Trivial state machine to determine who last changed the text properties
enum RichEditChangeState
{
Idle,
RichTextChanged,
PlainTextChanged,
Unknown
}
// Helper class that just stores a state inside a textbox, determining
// whether it is already being changed by code or not
class RichEditChangeStateHelper
{
public RichEditChangeState State { get; set; }
}
// Private attached property (never seen in XAML or anywhere else) to attach
// the state variable for us. Because this isn't used in XAML, we don't need
// the normal GetXXX and SetXXX static methods.
static readonly DependencyProperty RichEditChangeStateHelperProperty =
DependencyProperty.RegisterAttached("RichEditChangeStateHelper",
typeof(RichEditChangeStateHelper), typeof(RichEditBoxExtension), null);
// Inject our state into the textbox, and also attach an event-handler
// for the TextChanged event.
static void AttachRichEditBoxChangingHelper(DependencyObject o)
{
if (o.GetValue(RichEditChangeStateHelperProperty) != null)
return;
var richEdit = o as RichEditBox;
var helper = new RichEditChangeStateHelper();
o.SetValue(RichEditChangeStateHelperProperty, helper);
richEdit.TextChanged += (sender, args) =>
{
// To avoid re-entrancy, make sure we're not already changing
var state = GetState(o);
switch (state)
{
case RichEditChangeState.Idle:
string text = null;
richEdit.Document.GetText(Windows.UI.Text.TextGetOptions.None, out text);
if (text != GetPlainText(o))
{
SetState(o, RichEditChangeState.RichTextChanged);
o.SetValue(PlainTextProperty, text);
}
break;
case RichEditChangeState.PlainTextChanged:
SetState(o, RichEditChangeState.Idle);
break;
default:
Debug.Assert(false, "Unknown state");
SetState(o, RichEditChangeState.Idle);
break;
}
};
}
// Helper to set the state managed by the textbox
static void SetState(DependencyObject o, RichEditChangeState state)
{
(o.GetValue(RichEditChangeStateHelperProperty)
as RichEditChangeStateHelper).State = state;
}
// Helper to get the state managed by the textbox
static RichEditChangeState GetState(DependencyObject o)
{
return (o.GetValue(RichEditChangeStateHelperProperty)
as RichEditChangeStateHelper).State;
}
#endregion
}
附加属性基本上做了两件事,但是围绕着它有很多样板代码和状态机:
PlainText
附加属性更改时,它会使用 source.Document.SetText(TextSetOptions.None, text)< 将 RichEditBox
更新为纯文本
RichEditBox
文本更改(包括富文本更改)时,它会使用 richEdit.Document.GetText(TextGetOptions.None, out text)
然后是 o.SetValue(PlainTextProperty, text)
。请注意,这种基本方法可用于数据绑定(bind)您要根据实际数据可绑定(bind)属性计算的其他“派生”属性。
关于uwp - 如何在 UWP 中数据绑定(bind)到 RichEditBox 的纯文本值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49102980/
我不知道该怎么做... function f1() { var x = 10; function f2(fx) { var x; x = 6;
早期绑定(bind)和后期绑定(bind)有什么区别? 最佳答案 简短的回答是,早期(或静态)绑定(bind)是指编译时绑定(bind),后期(或动态)绑定(bind)是指运行时绑定(bind)(例如
如何在 SwiftUI View 上使用 Binding(get: { }, set: { }) 自定义绑定(bind)与 @Binding 属性。我已成功使用此自定义绑定(bind)与 @State
我经常发现自己遇到问题,即控件的两个(相关)值被更新,并且两者都会触发昂贵的操作,或者控件可能会暂时处于不一致的状态。 例如,考虑一个数据绑定(bind),其中两个值 (x,y) 相互减去,最终结果用
我想通过我的 ViewModel 控制我的一个窗口的高度和宽度。 这看起来很简单。 但没有。它不起作用。 它检查 ViewModel 的 Width但不是 Height . 奇怪的是,如果我切换 W
UI5中一次性绑定(bind)和单向绑定(bind)有什么区别? 是否有任何用户特定的用例我会使用它们? 我无法从文档中获得太多信息。 最佳答案 单程 它的作用:单向数据流。模型数据的变化(例如通过
(define make (lambda (x) (lambda (y) (cons x (list y))))) (let ((x 7) (p (make 4))) (cons
尽管我或多或少地了解什么是语言绑定(bind),但我很难理解它们是如何工作的。 例如,谁能解释一下如何为 WinAPI 制作 Java 绑定(bind)? 最佳答案 如果您搜索 Foreign Fun
谁能解释为什么我可以重新绑定(bind)列表但不能+? (binding [list vector] (list 1 3)) (binding [list +] (list 1 3)) (bi
我真的很喜欢 Caliburn 和命名约定绑定(bind),我很惊讶 可见性与“CanNAME”约定用于保护 Action 的方式不同。 据我所知, BooleanToVisibilityConver
我了解动态绑定(bind)的实现方式以及静态绑定(bind)和动态绑定(bind)之间的区别,但我只是无法理解动态绑定(bind)的定义。基本上它是一种运行时绑定(bind)类型。 最佳答案 基本上,
http://jsfiddle.net/3NRsd/ var foo = $("div").bind("click", function() { $("div").animate({"hei
这个问题我快疯了...我有一个用户控件,它有一个用于插入操作的 FormView 和一个用于所有其他操作的 GridView。 在这两个控件中,我都有一个 DropDownList,如下所示: '
我有一个绑定(bind)到 ListBox 的地址的 ObservableCollection。然后在 ItemTemplate 中,我使用 {Binding .} 绑定(bind)到当前地址记录。这
如果我有以下简单的 js/knockout 代码: .js( View 模型): var image = ko.observable('http://placehold.it/300x150'); 看
我正在 aurelia 上开发一个自定义属性,让用户在输入文本区域时从列表中进行选择。例如,用法将是这样的: 正如您可能注意到的,auto-complete是属性。现在,当我想显示提示时,我想在自定
我正在使用 EventEmitter2作为我的应用程序内部的消息总线。现在我需要绑定(bind)和取消绑定(bind)一些事件处理程序。因为我也希望他们bind将它们添加到给定的上下文中,我最终得到以
我有以下函数调用: $(".selector").on("click", callback.bind(this, param1, param2)); 在我的回调函数中,我想使用绑定(bind)的 th
我目前正在试验新的编译绑定(bind),并且(再次)达到了我在拼图中遗漏了一个小问题:为什么我必须调用 Bindings.Update?直到现在,我还认为实现 INotifyPropertyChang
我正在阅读一本关于编写 JavaScript 框架的书,并找到了这段代码。但是我不明白它是如何工作的,尤其是 bind.bind 的用法?有人知道吗? var bind = Function.prot
我是一名优秀的程序员,十分优秀!