Привязка usercontrol к противоположному свойству bool

Довольно просто: я хочу сделать то же самое, что , но в winforms. Все, что google, похоже, тянет вверх, зависит от wpf (т.е. Я не хочу ссылаться на presentationframework.dll)

Объясняется, если вы не хотите читать ссылку:

Ниже представлено представление о намерениях того, что я хотел бы сделать, хотя это явно не работает.

CheckBox1.DataBindings.Add(new Binding("Checked", this.object, "!SomeBool"));

Ответы

Ответ 1

У вас есть два варианта:

  • Создайте объект Binding вручную и прикрепите к Format и Parse и поменяйте значение в каждом.
  • Создайте дополнительное свойство класса, которое просто изменяет логику предполагаемого свойства

Первый вариант - более чистый, IMO, поскольку он не заставляет ваш API класса следовать вашему дизайну интерфейса, хотя второй вариант (незначительно) проще.

Пример варианта 1

private void SwitchBool(object sender, ConvertEventArgs e)
{ 
    e.Value = !((bool)e.Value);
}

...

Binding bind = new Binding("Checked", this.object, "SomeBool");

bind.Format += SwitchBool;
bind.Parse += SwitchBool;

CheckBox1.DataBindings.Add(bind);

Пример варианта 2

public class SomeClass
{
    public bool SomeBool { get; set; }

    public bool NotSomeBool
    {
        get { return !SomeBool; }
        set { SomeBool = !value; }
    }
}

...

CheckBox1.DataBindings.Add("Checked", this.object, "NotSomeBool");

Опять же, я очень одобряю вариант 1, поскольку для варианта 2 требуется, чтобы вы адаптировали свой класс к своему дизайну пользовательского интерфейса.

Ответ 2

Основываясь на ответе Адама, я написал небольшой класс-помощник:

class NegateBinding
{
    string propertyName;
    object dataSource;
    string dataMember;
    public NegateBinding(string propertyName, object dataSource, string dataMember)
    {
        this.propertyName = propertyName;
        this.dataSource = dataSource;
        this.dataMember = dataMember;
    }

    public static implicit operator Binding(NegateBinding eb)
    {
        var binding = new Binding(eb.propertyName, eb.dataSource, eb.dataMember, false, DataSourceUpdateMode.OnPropertyChanged);
        binding.Parse += new ConvertEventHandler(negate);
        binding.Format += new ConvertEventHandler(negate);
        return binding;
    }

    static void negate(object sender, ConvertEventArgs e)
    {
        e.Value = !((bool)e.Value);
    }
}

Теперь вы можете использовать его следующим образом:

label1.DataBindings.Add(new NegateBinding("Visible", otherObject, "HasData"));

Ответ 3

Чтобы сделать это, я выполнил свойство readonly с именем NotSomeBool, в том же классе, где у вас есть свойство SomeBool, и привяжите его к этому свойству.