WPF - 从绑定路径获取属性值

发布于 2024-09-16 07:19:08 字数 182 浏览 9 评论 0原文

如果我有一个名为 MyObject 的对象,它有一个名为 MyChild 的属性,它本身有一个名为 Name 的属性。如果我只有一个绑定路径(即“MyChild.Name”)和对 MyObject 的引用,如何获取该 Name 属性的值?

MyObject
  -MyChild
    -Name

if I have an object say called MyObject, which has a property called MyChild, which itself has a property called Name. How can I get the value of that Name property if all I have is a binding path (i.e. "MyChild.Name"), and a reference to MyObject?

MyObject
  -MyChild
    -Name

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

东京女 2024-09-23 07:19:08

我找到了一种方法来做到这一点,但它非常丑陋,而且可能不是很快...基本上,这个想法是创建一个与给定路径的绑定并将其应用于依赖对象的属性。这样,绑定就会完成检索值的所有工作:

public static class PropertyPathHelper
{
    public static object GetValue(object obj, string propertyPath)
    {
        Binding binding = new Binding(propertyPath);
        binding.Mode = BindingMode.OneTime;
        binding.Source = obj;
        BindingOperations.SetBinding(_dummy, Dummy.ValueProperty, binding);
        return _dummy.GetValue(Dummy.ValueProperty);
    }

    private static readonly Dummy _dummy = new Dummy();

    private class Dummy : DependencyObject
    {
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(Dummy), new UIPropertyMetadata(null));
    }
}

I found a way to do this, but it's quite ugly and probably not very fast... Basically, the idea is to create a binding with the given path and apply it to a property of a dependency object. That way, the binding does all the work of retrieving the value:

public static class PropertyPathHelper
{
    public static object GetValue(object obj, string propertyPath)
    {
        Binding binding = new Binding(propertyPath);
        binding.Mode = BindingMode.OneTime;
        binding.Source = obj;
        BindingOperations.SetBinding(_dummy, Dummy.ValueProperty, binding);
        return _dummy.GetValue(Dummy.ValueProperty);
    }

    private static readonly Dummy _dummy = new Dummy();

    private class Dummy : DependencyObject
    {
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(Dummy), new UIPropertyMetadata(null));
    }
}
同展鸳鸯锦 2024-09-23 07:19:08

我开发了一个 nuget 包 Pather.CSharp 正是您所需要的。

它包含一个 Resolver 类,该类具有一个 Resolve 方法,其行为类似于 @ThomasLevesque 的 GetValue 方法。
示例:

IResolver resolver = new Resolver(); 
var o = new { Property1 = Property2 = "value" } }; 
var path = "Property1.Property2";    
object result = r.Resolve(o, path); //the result is the string "value"

它甚至支持通过索引集合访问或通过密钥字典访问
这些路径的示例是:

"ArrayProperty[5]"
"DictionaryProperty[Key]"

I developed a nuget package Pather.CSharp that does exactly what you need.

It contains a class Resolver that has a Resolve method which behaves like @ThomasLevesque's GetValue method.
Example:

IResolver resolver = new Resolver(); 
var o = new { Property1 = Property2 = "value" } }; 
var path = "Property1.Property2";    
object result = r.Resolve(o, path); //the result is the string "value"

It even supports collection access via index or dictionary access via key.
Example paths for these are:

"ArrayProperty[5]"
"DictionaryProperty[Key]"
成熟的代价 2024-09-23 07:19:08

不确定你想做什么,但是以及如何做(xaml 或代码),但你总是可以命名你的对象

<MyObject x:Name="myBindingObject" ... />

,然后在代码

myBindingObject.Something.Name

或 xaml 中使用它

<BeginStoryboard>
 <Storyboard>
    <DoubleAnimation
        Storyboard.TargetName="myBindingObject"
        Storyboard.TargetProperty="Background"
        To="AA2343434" Duration="0:0:2" >
    </DoubleAnimation>
 </Storyboard>
</BeginStoryboard>

not sure what you want to do but and how (xaml or code) yet you can always name your object

<MyObject x:Name="myBindingObject" ... />

an then use it in code

myBindingObject.Something.Name

or in xaml

<BeginStoryboard>
 <Storyboard>
    <DoubleAnimation
        Storyboard.TargetName="myBindingObject"
        Storyboard.TargetProperty="Background"
        To="AA2343434" Duration="0:0:2" >
    </DoubleAnimation>
 </Storyboard>
</BeginStoryboard>
骷髅 2024-09-23 07:19:08

我就是这样做的。如果这是一个糟糕的主意,请告诉我,因为 C# 对我来说只是副业,所以我不是专家 objectToAddTo 的类型为 ItemsControl:

BindingExpression itemsSourceExpression = GetaBindingExression(objectToAddTo);
object itemsSourceObject = (object)itemsSourceExpression.ResolvedSource;
string itemSourceProperty = itemsSourceExpression.ResolvedSourcePropertyName;

object propertyValue = itemsSourceObject.GetType().GetProperty(itemSourceProperty).GetGetMethod().Invoke(itemsSourceObject, null); // Get the value of the property

I am doing it this way. Please let me know if this is a terrible idea, as C# is just a side job for me so I am not an expert objectToAddTo is of type ItemsControl:

BindingExpression itemsSourceExpression = GetaBindingExression(objectToAddTo);
object itemsSourceObject = (object)itemsSourceExpression.ResolvedSource;
string itemSourceProperty = itemsSourceExpression.ResolvedSourcePropertyName;

object propertyValue = itemsSourceObject.GetType().GetProperty(itemSourceProperty).GetGetMethod().Invoke(itemsSourceObject, null); // Get the value of the property
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文