Привязка 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
, и привяжите его к этому свойству.