wpf 存储bindingexpression以供以后使用

wsewodh2  于 2023-08-07  发布在  其他
关注(0)|答案(3)|浏览(87)

我有一个使用IsEnabled绑定的应用程序。我还需要删除此绑定一小会儿。
我创建了一个ControlBehavior,并附带了一个属性,用作临时存储位置。ClearIsEnabledBinding将设置此附加属性中使用的绑定。RestoreIsEnabeldBinding应该将绑定返回到原始位置。这不管用当绑定被清除时,附加属性也被清除。
场景是这样的。我有一个文本框,它通过转换器将IsEnabled绑定到视图模型。当我使用一个特定的函数时,所有的IsEnabled都应该为true,而不管viewmodel中的值是什么。这很简单,只需删除绑定并设置为true。但是当我从这个函数返回时,我需要用一个转换器将绑定恢复到它与视图模型的原始绑定。因此,我需要将整个bindingexpression保存在某个地方,然后再“放”回去
我的班级如下:
有什么建议我做错了什么吗?

public partial class ControlBehavior
{
    public static readonly DependencyProperty IsEnabledBindingProperty = DependencyProperty.RegisterAttached(
         "IsEnabledBinding",
         typeof(BindingExpression),
         typeof(ControlBehavior),
         new PropertyMetadata(null));

    public static void SetIsEnabledBinding(DependencyObject element, BindingExpression value)
    {
        if (value != null)
        {
            element.SetValue(IsEnabledBindingProperty, value);
            SetIsEnabledBindingSet(element, true);
        }
    }

    public static BindingExpression GetIsEnabledBinding(DependencyObject element)
    {
        var obj = element.GetValue(IsEnabledBindingProperty);
        return (BindingExpression) obj;
    }

    public static readonly DependencyProperty IsEnabledBindingSetProperty = DependencyProperty.RegisterAttached(
        "IsEnabledBindingSet",
        typeof(bool),
        typeof(ControlBehavior),
        new PropertyMetadata(false));

    public static void SetIsEnabledBindingSet(DependencyObject element, bool value)
    {
        element.SetValue(IsEnabledBindingSetProperty, value);
    }

    public static bool GetIsEnabledBindingSet(DependencyObject element)
    {
        return (bool)element.GetValue(IsEnabledBindingSetProperty);
    }

    public static void ClearIsEnabledBinding(DependencyObject element)
    {
        SetIsEnabledBinding(element, ((Control)element).GetBindingExpression(UIElement.IsEnabledProperty));
        ((Control)element).SetBinding(UIElement.IsEnabledProperty, new Binding());
    }

    public static void RestoreIsEnabledBinding(DependencyObject element)
    {
        if (!GetIsEnabledBindingSet(element))
        {
            return;
        }
        ((Control)element).SetBinding(UIElement.IsEnabledProperty, GetIsEnabledBinding(element).ParentBindingBase);
    }
}

字符串

pu3pd22g

pu3pd22g1#

我们已经使用下面的类来完成我认为你要实现的目标:

/// <summary>
/// Utilities to be used with common data binding issues
/// </summary>
class DataBindingUtils

{

    private static readonly DependencyProperty DummyProperty = DependencyProperty.RegisterAttached(

          "Dummy",

          typeof(Object),

          typeof(DependencyObject),

          new UIPropertyMetadata(null));


    /// <summary>
    /// Get a binding expression source value (using the PropertyPath), from MSDN forums:
    /// "Yes, there is one (class to provide the value) inside WPF stack, but it's an internal class"
    /// Get source value of the expression by creating new expression with the same
    /// source and Path, attaching this expression to attached property of type object
    /// and finally getting the value of the attached property
    /// </summary>
    /// <param name="expression"></param>
    /// <returns></returns>
    public static Object Eval(BindingExpression expression)

    {

        // The path might be null in case of expression such as: MyProperty={Binding} - in such case the value we'll get

        // will be the DataContext

        string path = null;

        if (expression.ParentBinding != null && expression.ParentBinding.Path != null)

        {

            path = expression.ParentBinding.Path.Path;

        }


        Binding binding = new Binding(path);

        binding.Source = expression.DataItem;

        DependencyObject dummyDO = new DependencyObject();

        BindingOperations.SetBinding(dummyDO, DummyProperty, binding);

        object bindingSource = dummyDO.GetValue(DummyProperty);

        BindingOperations.ClearBinding(dummyDO, DummyProperty);

        return bindingSource;

    }

}

字符串

dgenwo3n

dgenwo3n2#

场景是这样的。我有一个文本框,它通过转换器将IsEnabled绑定到视图模型。当我使用一个特定的函数时,所有的IsEnabled都应该为true,而不管viewmodel中的值是什么。这很简单,只需删除绑定并设置为true。但是当我从这个函数返回时,我需要用一个转换器将绑定恢复到它与视图模型的原始绑定
您可以提供一种机制来临时 overrideIsEnabled值,而不是处理绑定。我假设两件事:1)你正在绑定到某个东西(我们称之为IsEnabled)2)你正在创建某种 edit 模式,它应该临时覆盖绑定值:

bool _isEditMode;
public bool IsEditMode
{
    get { return _isEditMode; }
    set
    {
        _isEditMode = value;
        OnPropertyChanged(nameof(IsEnabled)); // update IsEnabled when IsEditMode changed
    }
}

bool _isEnabled;
public bool IsEnabled
{
    get
    {
        return IsEditMode || _isEnabled; // return true if IsEditMode == true or actual value otherwise
    }
    set
    {
        _isEnabled = value;
        OnPropertyChanged();
    }
}

字符串
现在如果你绑定

<TextBox IsEnable="{Binding IsEnabled, Converter= ...}" ... />


然后只要你设置IsEditMode = true文本框将成为启用.如果你设置IsEditMode = false文本框将再次启用或禁用取决于IsEnabled视图模型属性的值。

4xy9mtcn

4xy9mtcn3#

我使用一个按钮来存储BindingBase并在之后恢复它:

private async void RetryButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    System.Windows.Controls.Button button = (System.Windows.Controls.Button)sender;
    System.Windows.Data.BindingBase bindingBase = button.GetBindingExpression(UIElement.IsEnabledProperty).ParentBindingBase;
    button.IsEnabled = false; // This will remove the binding, which is what we want.

    await _pageViewModel.RetryAsync();

    _ = button.SetBinding(UIElement.IsEnabledProperty, bindingBase); // Add the binding back again.
}

字符串

相关问题