&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; } }}