gpt4 book ai didi

c# - XAML:如何将元素绑定(bind)到属性名称是动态的,在不同的地方可以有不同的名称

转载 作者:太空宇宙 更新时间:2023-11-03 12:37:13 27 4
gpt4 key购买 nike

我创建了一个带有 ListControl 的自定义 UserControl。

<UserControl>
<UserControl.Resources>
<Style TargetType="ItemsControl">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<simple:TrackItem />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<ItemsControl ItemsSource="{Binding ElementName=Root, Path=ItemsSource}"/>
</UserControl>

我还在这个自定义 UserControl 中创建了一个 DependencyProperty,并将 ListControl 的 ItemsSource 绑定(bind)到这个 DependencyProperty。

public partial class TracksList : UserControl
{
public TracksList()
{
InitializeComponent();
}

public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
"ItemsSource", typeof(IEnumerable), typeof(TracksList), new FrameworkPropertyMetadata(default(IEnumerable)));

public IEnumerable ItemsSource
{
get { return (IEnumerable) GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}

}

我覆盖了 ItemsControl 的 ItemTemplate。这个 ItemTemplate 有两个 TextBlock 元素,所以这个 TextBlocks 需要项目 DataType 的名称来将它们的文本值绑定(bind)到属性。

  <TextBlock Text="{Binding "????????"}"/>
<TextBlock Text="{Binding "????????"}"/>

而不是“????????”我想动态设置此属性的名称 - 通过自定义 UserControl 中的自定义字符串属性。

[这不是工作代码,我删除了不需要的部分以使其更具可读性]

最佳答案

您可以使用一个简单的多值转换器来做到这一点:

public class NamedPropertyValueConverter : IMultiValueConverter
{
public object Convert(
object[] values, Type targetType, object parameter, CultureInfo culture)
{
var sourceObj = values[0];
var propName = values[1].ToString();

var propInfo = sourceObj.GetType().GetProperty(propName);

return propInfo.GetValue(sourceObj);
}

public object[] ConvertBack(
object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

示例 XAML:

<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Window.Resources>
<local:NamedPropertyValueConverter x:Key="NamedPropertyValue" />
</Window.Resources>
<Grid>
<StackPanel Orientation="Vertical" >
<TextBox Text="{Binding Foo, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource NamedPropertyValue}">
<Binding />
<Binding Path="PropertyNameProp" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Grid>

这是我测试过的一个简单的 View 模型:

public class ViewModel : ViewModelBase
{
#region Foo Property
private String _foo = "Initial value of Foo";
public String Foo
{
get { return _foo; }
set
{
if (value != _foo)
{
_foo = value;
OnPropertyChanged();
OnPropertyChanged(nameof(PropertyNameProp));
// This works too, but all properties will be requeried.
// In some cases that may be too expensive.
//OnPropertyChanged(null);
}
}
}
#endregion Foo Property

#region PropertyNameProp Property
private String _propertyNameProp = "Foo";
public String PropertyNameProp
{
get { return _propertyNameProp; }
set
{
if (value != _propertyNameProp)
{
_propertyNameProp = value;
OnPropertyChanged();
}
}
}
#endregion PropertyNameProp Property
}

请注意,Foo 在其值更改时必须调用 OnPropertyChanged(nameof(PropertyNameProp))。否则,Binding 将不知道有任何更改并且不会更新,因为 Binding 不知道 Foo 存在。

如果你想为这个转换器实现 ConvertBack,你需要重新考虑一下,但如果你把值放在 TextBlock s。

关于c# - XAML:如何将元素绑定(bind)到属性名称是动态的,在不同的地方可以有不同的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40450712/

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