簡體   English   中英

綁定綁定的路徑屬性

[英]Binding the Path Property of a Binding

是否可以將綁定的Path屬性綁定到另一個屬性?

我想實現以下代碼:

Text="{Binding Path={Binding Path=CurrentPath}}"

因此,我可以動態調整實際綁定所引用的屬性。

感謝您的幫助Jonny

正如其他張貼者所提到的,您只能在依賴項屬性上設置綁定-路徑不是。 根本原因是xaml是要編譯的源代碼。 在編譯時,編譯器不知道“ CurrentPath”的值是什么,因此將無法編譯。 本質上,您要執行的操作是對屬性值進行運行時反射-可以使用要綁定到的ViewModel中的另一個屬性或使用轉換器來完成。

視圖模型:

public string CurrentValue
{
    get
    {
         var property = this.GetType().GetProperty(CurrentPath);
         return property.GetValue(this, null);
    }
} 

使用轉換器:

public class CurrentPathToValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var viewModel = (ViewModel)value;
        var property = viewModel.GetType().GetProperty(viewModel.CurrentPath);
        var currentValue = property.GetValue(viewModel, null);
        return currentValue;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

當然,這些僅在您想要獲得對象的簡單屬性時才有效-如果您想要更復雜的東西,則反射代碼將變得更復雜。

除非您要構建諸如屬性網格之類的東西,或者出於某些其他原因而確實想對應用程序中運行的對象進行自省,否則我建議您重新設計,因為反射實際上僅適用於少數情況。

我自己解決了。

這是解決方案,我希望它可以幫助任何人遇到像我一樣的問題。

public class CustomBindingBehavior : Behavior<FrameworkElement>
{
    public bool IsBinding
    {
        get
        {
            return (bool)GetValue(IsBindingProperty);

        }
        set
        {
            SetValue(IsBindingProperty, value);
        }
    }

    public string PropertyPath
    {
        get
        {
            return (string)GetValue(PropertyPathProperty);

        }
        set
        {
            SetValue(PropertyPathProperty, value);
        }
    }

    public static DependencyProperty
        PropertyPathProperty = DependencyProperty.Register("PropertyPath", typeof(string),
                        typeof(CustomBindingBehavior), null);

    public static DependencyProperty
        IsBindingProperty = DependencyProperty.Register("IsBinding", typeof(bool),
                        typeof(CustomBindingBehavior), null);

    protected override void OnAttached()
    {
        if (AssociatedObject is TextBlock)
        {
            var tb = AssociatedObject as TextBlock;
            tb.Loaded += new RoutedEventHandler(tb_Loaded);
        }
    }

    private void tb_Loaded(object sender, RoutedEventArgs e)
    {
        AddBinding(sender as TextBlock, TextBlock.TextProperty);
    }

    private void AddBinding(DependencyObject targetObj, DependencyProperty targetProp)
    {
        if (IsBinding)
        {
            Binding binding = new Binding();
            binding.Path = new PropertyPath(this.PropertyPath, null);

            BindingOperations.SetBinding(targetObj, targetProp, binding);
        }
        else
        {
            targetObj.SetValue(targetProp, this.PropertyPath);
        }
    }
}

這是XAML中的實現:

<TextBlock >
                <i:Interaction.Behaviors>
                    <behaviors:CustomBindingBehavior PropertyPath="{Binding Path=HeaderPropertyBinding}" IsBinding="{Binding Path=HeaderIsBinding}" />
                </i:Interaction.Behaviors>
            </TextBlock>

喬尼問候

路徑不是依賴項屬性,因此綁定將不起作用。

也許您可以綁定到一個屬性,該屬性根據switch語句返回另一個屬性,然后綁定到該屬性。 更改“ switch”屬性,然后更改其他屬性的輸出。 只是不要忘了將您的NotifyPropertyChanged內容包含在bound屬性的switch屬性中,否則您的視圖將不會更新。 例如

private int _mySwitch;

//Set this to determine what the other property will return.
public int SwitchProperty
{
    get { return _mySwitch; }
    set
    {
        _mySwitch = value;
        NotifyPropertyChanged("MySwitchableProperty");
    }
}
public String PropertyA { get; set; }
public String PropertyB { get; set; }

//Bind to this property
public String MySwitchableProperty
{
    get
    {
        switch (SwitchProperty)
        {
            case 1:
                return PropertyA;
                break;
            case 2:
                return PropertyB;
                break;
            default :
                return String.Empty;
                break;
        }
    }
}

我認為轉換器可以幫助您。 Expample

第一控制

Text="{Binding Path=CurrentPath}"

第二控制

Text="{Binding Path=CurrentPath, Convertor={converters:MyConvertor}}"

基本轉換器

public abstract class ConvertorBase<T> : MarkupExtension, IValueConverter
    where T : class, new()
    {
            public abstract object Convert(object value, Type targetType, object parameter,
            CultureInfo culture);

            public virtual object ConvertBack(object value, Type targetType, object parameter,
            CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #region MarkupExtension members

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_converter == null)
                _converter = new T();
            return _converter;
        }

        private static T _converter = null;

        #endregion
    }

MyConverter

 public class MyConverter: ConvertorBase<MyConverter>
    {
        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return (string)value.Equals("blabla") ? "Yes" : "No"; // here return necessary parametr
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM