gpt4 book ai didi

wpf - 将文本绑定(bind)到附加属性

转载 作者:行者123 更新时间:2023-12-02 22:16:19 27 4
gpt4 key购买 nike

我的问题与此类似:WPF Generate TextBlock Inlines但我没有足够的声誉来发表评论。这是附加的属性类:

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);
}
}
}

我正在使用这个附加的属性类,并尝试将其应用到文本 block ,以使文本识别 View 模型类中字符串中的内联值,例如粗体、下划线等。我的文本 block 中有以下 XAML:

<TextBlock Grid.Row="1" Grid.Column="1" TextWrapping="Wrap" my:Attached.FormattedText="test" />

但是,当我启动程序时,我在文本 block 中什么也没有得到。我还想最终将文本绑定(bind)到我的 View 模型上的属性,但希望首先显示一些内容......

抱歉,这可能是一个新手问题,但我不明白为什么它不起作用。它在这里没有给我任何错误,只是没有显示出来。如果我尝试绑定(bind),它会给我错误:

{"A 'Binding' cannot be set on the 'SetFormattedText' property of type 'TextBlock'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject."}

最佳答案

首先,属性的类型需要是类名,而不是类型 TextBlock:

public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached(
"FormattedText",
typeof(string),
typeof(TextBlock), <----- Here

其次,handler没有被调用,它必须在这里注册:

new FrameworkPropertyMetadata(string.Empty, 
FrameworkPropertyMetadataOptions.AffectsMeasure,
YOUR_PropertyChanged_HANDLER)

第三,一个工作示例,您需要像这样指定输入字符串:

<Bold>My little text</Bold>

工作示例如下:

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>

代码隐藏

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);
}
}
}

最初是纯文本,点击按钮后将被分配为内联文本。

MVVM 版本示例

要在 MVVM 风格中使用此示例,您需要在 Model/ViewModel 中创建适当的属性,并将其与附加的依赖属性相关联,如下所示:

<TextBlock Name="TestText"
PropertiesExtension:TextBlockExt.FormattedText="{Binding Path=InlineText,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
Width="200"
Height="100"
TextWrapping="Wrap" />

Model/ViewModel 中的属性必须支持方法 NotifyPropertyChanged

这是一个完整的示例:

附加属性

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);
}
}
}

MainViewModel

public class MainViewModel : NotificationObject
{
private string _inlineText = "";

public string InlineText
{
get
{
return _inlineText;
}

set
{
_inlineText = value;
NotifyPropertyChanged("InlineText");
}
}
}

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>

代码隐藏(仅用于测试)

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>";
}
}

This example is available at this link.

关于wpf - 将文本绑定(bind)到附加属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21894206/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com