Your setting of Button.Click
isn't assigning the event handler to the Button. It's assigning it to the ListBox
. It works because of WPF's routed event system.
If you want the Button
to take on a value set at the level of the ListBox
, one option in this case is to use a Binding
with a RelativeSource
:
<Button Content="{Binding Tag, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}"/>
In this case I've just hijacked the Tag
property, which you can specify as follows:
<ListBox Tag="This is the button's content" .../>
Another option is to use an inherited attached property. For example:
<Button Content="{Binding local:MyClass.MyAttachedProperty}"/>
And then:
<ListBox local:MyClass.MyAttachedProperty="This is the button's content"/>
Finally, if you were templating the ListBox
itself, you can "reach out" and bind to a property of the control you're templating using a TemplateBinding
:
<Button Content="{TemplateBinding Tag}"/>
Of course, this technique is generally used with properties specifically declared on the templated control. For example, you could subclass ListBox
and add your own ButtonContent
property. Then, in your template you could reach out and bind to that property from the Button
.
You can use a ValueConverter that inverts a bool property for you.
XAML:
IsEnabled="{Binding Path=IsReadOnly, Converter={StaticResource InverseBooleanConverter}}"
Converter:
[ValueConversion(typeof(bool), typeof(bool))]
public class InverseBooleanConverter: IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (targetType != typeof(bool))
throw new InvalidOperationException("The target must be a boolean");
return !(bool)value;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
#endregion
}
Best Answer
You can use implicit styles:
Of course you can add triggers as well.