Tag: WPF/バインディング

目次

参考情報

Tips

Bindingを複製する

BindingExpressionからソースのプロパティ値を取得する

  • c# - How to resolve bound object from bindingexpression with WPF? - Stack Overflowが参考になる。
  • binding.PathよりPropertyInfoを使って簡単にとれそうだが、Pathには"foo.bar"形式やインデックス形式が許されるので一筋縄ではいかない。
  • まじめにやるには次の通り(ただしインデックスには対応していない)
    public static T GetValue<T>(this BindingExpression expression, object dataItem)            
    {
        if (expression == null || dataItem == null)
        {
            return default(T);
        }
    
        string bindingPath = expression.ParentBinding.Path.Path;
        string[] properties = bindingPath.Split('.');
    
        object currentObject = dataItem;
        Type currentType = null;
    
        for (int i = 0; i < pathParts.Length; i++)
        {
            currentType = currentObject.GetType();                
            PropertyInfo property = currentType.GetProperty(properties[i]);
            if (property == null)
            {                    
                currentObject = null;
                break;
            }
            currentObject = property.GetValue(currentObject, null);
            if (currentObject == null)
            {
                break;
            }
        }
    
        return (T)currentObject;
    }
    
  • 一時的にダミーのバインディングを作って値を取得する荒技。
    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));
        }
    }
    

トラブルシューティング

ItemsSourceにバインディングしているのに表示されない。

  • 例えばViewModeを以下のように定義し、MessagesをItemsSourceにBindしても表示されない。
            public LogWindowVM()
            {
                Messages = new ObservableCollection<string>();
                Messages.Add("abc");
                Messages.Add("def");
            }
    
            public ObservableCollection<string> Messages;
    
  • それはWPFのバインディングがプロパティに対して働くため。publicフィールドだとうまくいかない。c# - XAML: Confusing about binding - Stack Overflowより。
  • ということで。以下のようにする。
            public LogWindowVM()
            {
                Messages = new ObservableCollection<string>();
                Messages.Add("abc");
                Messages.Add("def");
            }
    
            public ObservableCollection<string> Messages {get; set; }
    

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-04-13 (水) 16:47:48