5

FrameworkElementをWPFページのStackPanelからプログラムで作成されたStackPanelに転送しています。ある時点で、バインディングを更新してプロパティ値を取得する必要があります。

この時点で、すべてのバインディング式に対してFrameworkElement.DataContext正しい値があります。BindingExpression.Status==BindingStatus.Unattachedを実行BindingExpression.UpdateTargetしましたが、プロパティ値が空です。

BindingExpression.UpdateTarget()のソースコードを見つけました:

    public override void UpdateTarget() 
    {
        if (Status == BindingStatus.Detached) 
            throw new InvalidOperationException(SR.Get(SRID.BindingExpressionIsDetached)); 

        if (Worker != null) 
        {
            Worker.RefreshValue();  // calls TransferValue
        }
    } 

ワーカーは内部オーバーライドvoidでインスタンスを取得しますBindingExpression.Activate()。また、Activate()内でBindingExpression.StatusがBindingStatus.Activeに設定されています。

プログラムで実行を開始しBindingExpression.Activate()、その後UpdateTargetを作成するにはどうすればよいですか?

アップデート

ここでの解決策(ありがとう、Olli):

public  void UpdateAllBindingTargets( DependencyObject obj)
    {

        FrameworkElement visualBlock = obj as FrameworkElement;
        if (visualBlock==null)
            return;
        if (visualBlock.DataContext==null)
            return;
        Object objDataContext = visualBlock.DataContext;

        IEnumerable<KeyValuePair<DependencyProperty, BindingExpression>> allElementBinding = GetAllBindings(obj);
        foreach (KeyValuePair<DependencyProperty, BindingExpression> bindingInfo in allElementBinding)
        {
            BindingOperations.ClearBinding(obj, bindingInfo.Key);

            Binding myBinding = new Binding(bindingInfo.Value.ParentBinding.Path.Path);
            myBinding.Source = objDataContext;
            visualBlock.SetBinding(bindingInfo.Key, myBinding);
            BindingOperations.GetBindingExpression(visualBlock, bindingInfo.Key).UpdateTarget();

        }

    }

オブジェクトのすべてのバインディングを取得する場所:

public  IEnumerable<KeyValuePair<DependencyProperty, BindingExpression>> GetAllBindings( DependencyObject obj)
    {
        var stack = new Stack<DependencyObject>();

        stack.Push(obj);

        while (stack.Count > 0)
        {
            var cur = stack.Pop();
            var lve = cur.GetLocalValueEnumerator();

            while (lve.MoveNext())
                if (BindingOperations.IsDataBound(cur, lve.Current.Property))
                {
                    KeyValuePair<DependencyProperty,BindingExpression> result=new KeyValuePair<DependencyProperty, BindingExpression>(lve.Current.Property,lve.Current.Value as BindingExpression);
                    yield return result;
                }

            int count = VisualTreeHelper.GetChildrenCount(cur);
            for (int i = 0; i < count; ++i)
            {
                var child = VisualTreeHelper.GetChild(cur, i);
                if (child is FrameworkElement)
                    stack.Push(child);
            }
        }
    }
4

1 に答える 1

3

プログラムで新しいバインディングを作成できます。これでうまくいくはずです。

http://msdn.microsoft.com/en-us/library/ms752347.aspx#creating_a_binding

MSDNページの例

MyData myDataObject = new MyData(DateTime.Now);      
Binding myBinding = new Binding("MyDataProperty");
myBinding.Source = myDataObject;
myText.SetBinding(TextBlock.TextProperty, myBinding);
于 2012-10-12T05:48:24.827 に答える