&tag(WPF/バインディング);
*目次 [#kb03ff08]
#contents
*参考情報 [#hc0686eb]

*Tips [#n9a62b2d]
**Bindingを複製する [#j5fca92a]
-[[c# - Binding does not have a Clone method, whats an effective way to copy it - Stack Overflow:http://stackoverflow.com/questions/1911532/binding-does-not-have-a-clone-method-whats-an-effective-way-to-copy-it]]
-BindingクラスにはCloneが存在しないので自前でコピーするしかないらしい。


**BindingExpressionからソースのプロパティ値を取得する [#za31e7dd]
-[[c# - How to resolve bound object from bindingexpression with WPF? - Stack Overflow:http://stackoverflow.com/questions/1549785/how-to-resolve-bound-object-from-bindingexpression-with-wpf]]が参考になる。
-binding.PathよりPropertyInfoを使って簡単にとれそうだが、Pathには"foo.bar"形式やインデックス形式が許されるので一筋縄ではいかない。
-まじめにやるには次の通り(ただしインデックスには対応していない)
#pre{{
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;
}
}}
-一時的にダミーのバインディングを作って値を取得する荒技。
#pre{{
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));
    }
}
}}

*トラブルシューティング [#ma2cdb51]
**ItemsSourceにバインディングしているのに表示されない。 [#b3cd3379]
-例えばViewModeを以下のように定義し、MessagesをItemsSourceにBindしても表示されない。
#pre{{
        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:http://stackoverflow.com/questions/25050239/xaml-confusing-about-binding]]より。
-ということで。以下のようにする。
#pre{{
        public LogWindowVM()
        {
            Messages = new ObservableCollection<string>();
            Messages.Add("abc");
            Messages.Add("def");
        }

        public ObservableCollection<string> Messages {get; set; }
}}





トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS