将字符串项绑定到 xaml 中字符串的依赖属性列表
Posted
技术标签:
【中文标题】将字符串项绑定到 xaml 中字符串的依赖属性列表【英文标题】:Binding string items to a dependency property list of strings in xaml 【发布时间】:2022-01-18 17:19:42 【问题描述】:我有一个定义为依赖属性的字符串列表。我通过 xaml 分配列表项的值。我可以分配文字字符串值,但我不知道如何将这些值绑定到 viewmodel 中的数据。
public static readonly DependencyProperty StringArgsProperty = DependencyProperty.Register(
"StringArgs", typeof(List<string>), typeof(GameTextBlock), new FrameworkPropertyMetadata(new List<string>()));
public List<string> StringArgs
get return (List<string>)GetValue(StringArgsProperty);
set SetValue(StringArgsProperty, value);
以下是我目前如何将项目绑定到所述列表:
<common:GameTextBlock.StringArgs>
<sys:String>arg1</sys:String>
<sys:String>arg2</sys:String>
</common:GameTextBlock.StringArgs>
我想要做的是将 arg1/arg2 替换为 ViewModel 中的值。如果我没有分配给列表的项目,我可以执行“Binding NameOfField”。
我不想在 ViewModel 中创建整个列表并绑定列表,因为我希望能够仅使用 xaml 来挑选项目。这可以实现吗?
编辑:我想要实现的更清晰的示例:
public class ViewModel
public string Item1 get; set;
public string Item2 get; set;
public string Item3 get; set;
然后我希望能够在一个包含多个 GameTextBlock 的 xaml 中使用它们,如下所示:
<GameTextBlock x:Name = "txt1" >
<GameTextBlock.StringArgs>
<sys:String>Binding VMItem1</sys:String>
<sys:String>Binding VMItem3</sys:String>
</GameTextBlock.StringArgs>
</GameTextBlock>
<GameTextBlock x:Name = "txt2" >
<GameTextBlock.StringArgs>
<sys:String>Binding VMItem1</sys:String>
<sys:String>Binding VMItem2</sys:String>
</GameTextBlock.StringArgs>
</GameTextBlock>
<GameTextBlock x:Name = "txt3" >
<GameTextBlock.StringArgs>
<sys:String>Binding VMItem1</sys:String>
</GameTextBlock.StringArgs>
</GameTextBlock>
【问题讨论】:
不要使用new FrameworkPropertyMetadata(new List<string>())
。对于 GameTextBlock 的所有实例,它将是相同的列表。使用new FrameworkPropertyMetadata(null)
并在构造函数中初始化StringArgs
最好在构造函数中通过SetCurrentValue(StringArgsProperty, new List<string>())
来实现。
@user2396632:从哪里“挑选”什么项目?所有项目都应在视图模型中定义。
@mm8 视图模型中定义的项目。我可以通过在 GameTextBlock 中创建属性“Arg0、Arg1、Arg2...”然后像 xaml 页面上的静态数据无法更改。将列表结构移动到依赖属性的更改处理程序后面和上的代码根据需要移动数据到属性列表。无论如何,这就是应该的方式。
如果您需要双向传输,那么您将需要更多代码来将数据从页面上的控制列表移回存储;不过,这可以用作模板。
后面的控制代码
数据列表
以下是自定义控件上要拆分到的列表:
public partial class ShowDependency : UserControl, INotifyPropertyChanged
private List<string> _Text1;
public List<string> Text1
get return _Text1;
set _Text1 = value; OnPropertyChanged(nameof(Text1));
private List<string> _Text2;
public List<string> Text2
get return _Text2;
set _Text2 = value; OnPropertyChanged(nameof(Text2));
带有 PropertyChanged 处理程序的依赖属性
这是保存来自 VM 的传入列表的依赖属性
#region public List<string> Storage
/// <summary>Storage is a transfer from the Main VM</summary>
public List<string> Storage
get => (List<string>)GetValue(StorageProperty);
set => SetValue(StorageProperty, value);
/// <summary>Identifies the Storage dependency property.</summary>
public static readonly DependencyProperty StorageProperty =
DependencyProperty.Register(
"Storage",
typeof(List<string>),
typeof(ShowDependency),
new PropertyMetadata(null, OnStoragePropertyChanged));
更改处理程序
一旦绑定,它会将数据添加到列表中。
/// <summary>StorageProperty property changed handler.</summary>
/// <param name="d">ShowDependency that changed its Storage.</param>
/// <param name="e">Event arguments.</param>
private static void OnStoragePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
if (d is ShowDependency source)
var value = (List<string>)e.NewValue;
if (value != null)
var l1 = new List<string>();
var l2 = new List<string>();
int count = 1;
foreach (var item in value)
if ((count++ % 2) == 0)
l1.Add(item);
else
l2.Add(item);
source.Text1 = l1;
source.Text2 = l2;
#endregion public List<string> Storage
主虚拟机上的字符串绑定列表
new List<string>() "Alpha", "Baker", "Tango", "Omega"
自定义控制页面
<UserControl x:Class="ExamplesInWPF.Controls.ShowDependency"
...
d:DesignHeight="450" d:DesignWidth="800"
x:Name="MyUserControl">
<StackPanel Orientation="Vertical">
<ListBox Margin="6" ItemsSource="Binding Text1, ElementName=MyUserControl"/>
<ListBox Margin="6" ItemsSource="Binding Text2, ElementName=MyUserControl"/>
</StackPanel>
</UserControl>
结果
顺便说一句,我一直使用这些 Control 依赖属性 sn-ps
Helpful Silverlight Snippets
忽略 Silverlight 部分,它们仍然很好,并且适用于 .Net 6 Xaml/WPF。
【讨论】:
以上是关于将字符串项绑定到 xaml 中字符串的依赖属性列表的主要内容,如果未能解决你的问题,请参考以下文章
TreeView ItemSsource 绑定到 ViewModel 不更新 xaml 控件项