sfa*_*ust 3 wpf xaml textblock mvvm attached-properties
我的问题与此类似:WPF生成TextBlock内联,但我没有足够的声誉来评论.这是附加的属性类:
public class Attached
{
public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
"FormattedText",
typeof(string),
typeof(TextBlock),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure));
public static void SetFormattedText(DependencyObject textBlock, string value)
{
textBlock.SetValue(FormattedTextProperty, value);
}
public static string GetFormattedText(DependencyObject textBlock)
{
return (string)textBlock.GetValue(FormattedTextProperty);
}
private static void FormattedTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textBlock = d as TextBlock;
if (textBlock == null)
{
return;
}
var formattedText = (string)e.NewValue ?? string.Empty;
formattedText = string.Format("<Span xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">{0}</Span>", formattedText);
textBlock.Inlines.Clear();
using (var xmlReader = XmlReader.Create(new StringReader(formattedText)))
{
var result = (Span)XamlReader.Load(xmlReader);
textBlock.Inlines.Add(result);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用这个附加的属性类,并尝试将其应用于文本块,以使文本识别我的视图模型类中的字符串中的粗体,下划线等内联值.我的文本块中有以下XAML:
<TextBlock Grid.Row="1" Grid.Column="1" TextWrapping="Wrap" my:Attached.FormattedText="test" />
Run Code Online (Sandbox Code Playgroud)
但是,当我启动程序时,文本块中什么都没有.我还希望最终将文本绑定到我的视图模型上的属性,但是想要先显示一些内容......
对不起,这可能是一个新手问题,但我无法弄清楚为什么它不起作用.它没有给我任何错误,只是没有显示.如果我尝试绑定,它会给我错误:
{"A'Binding'不能在'TextBlock'类型的'SetFormattedText'属性上设置.'Binding'只能在DependencyObject的DependencyProperty上设置."}
首先,属性的类型需要是类名,而不是类型TextBlock:
public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
"FormattedText",
typeof(string),
typeof(TextBlock), <----- Here
Run Code Online (Sandbox Code Playgroud)
其次,处理程序未被调用,必须在此处注册:
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsMeasure,
YOUR_PropertyChanged_HANDLER)
Run Code Online (Sandbox Code Playgroud)
第三,一个工作的例子,你需要指定输入字符串,如下所示:
<Bold>My little text</Bold>
Run Code Online (Sandbox Code Playgroud)
工作示例如下:
XAML
<Window x:Class="InlineTextBlockHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:this="clr-namespace:InlineTextBlockHelp"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Name="TestText"
this:AttachedPropertyTest.FormattedText="TestString"
Width="200"
Height="100"
TextWrapping="Wrap" />
<Button Name="TestButton"
Width="100"
Height="30"
VerticalAlignment="Top"
Content="TestClick"
Click="Button_Click" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
Code-behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string inlineExpression = "<Bold>Once I saw a little bird, go hop, hop, hop.</Bold>";
AttachedPropertyTest.SetFormattedText(TestText, inlineExpression);
}
}
public class AttachedPropertyTest
{
public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
"FormattedText",
typeof(string),
typeof(AttachedPropertyTest),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure, FormattedTextPropertyChanged));
public static void SetFormattedText(DependencyObject textBlock, string value)
{
textBlock.SetValue(FormattedTextProperty, value);
}
public static string GetFormattedText(DependencyObject textBlock)
{
return (string)textBlock.GetValue(FormattedTextProperty);
}
private static void FormattedTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textBlock = d as TextBlock;
if (textBlock == null)
{
return;
}
var formattedText = (string)e.NewValue ?? string.Empty;
formattedText = string.Format("<Span xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">{0}</Span>", formattedText);
textBlock.Inlines.Clear();
using (var xmlReader = XmlReader.Create(new StringReader(formattedText)))
{
var result = (Span)XamlReader.Load(xmlReader);
textBlock.Inlines.Add(result);
}
}
}
Run Code Online (Sandbox Code Playgroud)
最初是纯文本,点击Button后将分配给内联文本.
Example for MVVM version
要在MVVM样式中使用此示例,您需要在其中创建适当的属性,Model/ViewModel并将其与附加的依赖项属性关联,如下所示:
<TextBlock Name="TestText"
PropertiesExtension:TextBlockExt.FormattedText="{Binding Path=InlineText,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
Width="200"
Height="100"
TextWrapping="Wrap" />
Run Code Online (Sandbox Code Playgroud)
属性Model/ViewModel必须支持方法NotifyPropertyChanged.
这是一个完整的示例:
AttachedProperty
public class TextBlockExt
{
public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
"FormattedText",
typeof(string),
typeof(TextBlockExt),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsMeasure, FormattedTextPropertyChanged));
public static void SetFormattedText(DependencyObject textBlock, string value)
{
textBlock.SetValue(FormattedTextProperty, value);
}
public static string GetFormattedText(DependencyObject textBlock)
{
return (string)textBlock.GetValue(FormattedTextProperty);
}
private static void FormattedTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textBlock = d as TextBlock;
if (textBlock == null)
{
return;
}
var formattedText = (string)e.NewValue ?? string.Empty;
formattedText = string.Format("<Span xml:space=\"preserve\" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">{0}</Span>", formattedText);
textBlock.Inlines.Clear();
using (var xmlReader = XmlReader.Create(new StringReader(formattedText)))
{
var result = (Span)XamlReader.Load(xmlReader);
textBlock.Inlines.Add(result);
}
}
}
Run Code Online (Sandbox Code Playgroud)
MainViewModel
public class MainViewModel : NotificationObject
{
private string _inlineText = "";
public string InlineText
{
get
{
return _inlineText;
}
set
{
_inlineText = value;
NotifyPropertyChanged("InlineText");
}
}
}
Run Code Online (Sandbox Code Playgroud)
MainWindow.xaml
<Window x:Class="InlineTextBlockHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:InlineTextBlockHelp.ViewModels"
xmlns:PropertiesExtension="clr-namespace:InlineTextBlockHelp.PropertiesExtension"
Title="MainWindow" Height="350" Width="525"
ContentRendered="Window_ContentRendered">
<Window.DataContext>
<ViewModels:MainViewModel />
</Window.DataContext>
<Grid>
<TextBlock Name="TestText"
PropertiesExtension:TextBlockExt.FormattedText="{Binding Path=InlineText,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
Width="200"
Height="100"
TextWrapping="Wrap" />
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
Code-behind (just for test)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_ContentRendered(object sender, EventArgs e)
{
MainViewModel mainViewModel = this.DataContext as MainViewModel;
mainViewModel.InlineText = "<Bold>Once I saw a little bird, go hop, hop, hop.</Bold>";
}
}
Run Code Online (Sandbox Code Playgroud)
此示例可在此处获得
link.
| 归档时间: |
|
| 查看次数: |
2891 次 |
| 最近记录: |