WPF 和 XAML 与 HTML 不同,都是关于 数据。
考虑和推理任何基于 XAML 的 UI 的最佳方式是考虑您需要显示和交互的数据。
在这种情况下:
public class Word
{
public string Value { get; set; }
public bool IsEditable { get; set; }
}
将代表我们的每一个词。那么你只需要一个列表:
public class ViewModel
{
public List<Word> Words { get; private set; }
public ViewModel()
{
var editableWords = new[] { "on", "of" };
var text = "Do you know someone rich and famous? Is he confident, popular, and joyful all of the time—the epitome of mainstream success? Or, on the other hand, is he stressed, having second thoughts about his life choices, and unsure about the meaning of his life?";
this.Words =
text.Split(' ')
.Select(x => new Word
{
Value = x,
IsEditable = editableWords.Contains(x.ToLower())
})
.ToList();
}
}
请注意我如何将文本转换为 List<Word> 并在需要的位置设置 IsEditable。
现在只需使用ItemsControl 来显示这些:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>
<ItemsControl ItemsSource="{Binding Words}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="5,2,5,2">
<TextBlock Text="{Binding Value}"
VerticalAlignment="Center"/>
<TextBox Text="{Binding Value}"
Visibility="{Binding IsEditable, Converter={StaticResource BoolToVis}}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
最后,将DataContext 设置为我们的 ViewModel 的一个实例:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
结果:
请注意,我根本没有在代码中“接触” UI,这只是简单、简单的属性和 DataBinding。