Let’s say I have a Border whose DataContext is an object of type MyViewModel. MyViewModel has bool properties called RoundLeft and RoundRight. When RoundLeft is true, I want the CornerRadius of the border to be 6,0,0,6. When RoundRight is true, I want 0,6,6,0. When both are true, I want 6,6,6,6.
I’ve described my first two attempts below. I haven’t given up yet, but I wanted to see if anyone else might have any ideas.
Attempt #1
I got it partially working by binding to the MyViewModel instance itself (not a specific property) and using an IValueConverter that builds the correct CornerRadius object. This works on initial load. The problem is that the binding is monitoring changes of the object as a whole rather than changes to the specific RoundLeft and RoundRight properties, e.g. if RoundLeft changes, the border’s CornerRadius doesn’t.
Binding:
<Border CornerRadius="{Binding Converter={StaticResource myShiftCornerRadiusConverter}}" />
Converter:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var myViewModel = value as MyViewModel;
if (myViewModel != null)
{
return new CornerRadius(
myViewModel.RoundLeft ? 6 : 0,
myViewModel.RoundRight ? 6 : 0,
myViewModel.RoundRight ? 6 : 0,
myViewModel.RoundLeft ? 6 : 0);
}
else
{
return new CornerRadius(6);
}
}
Attempt #2
This blog post from Colin Eberhardt looked promising, but I’m getting vague XamlParseExceptions and ComExceptions. Here’s my XAML:
<Border>
<ce:MultiBindings>
<ce:MultiBinding TargetProperty="CornerRadius" Converter="{StaticResource myCornerRadiusConverter}">
<ce:MultiBinding.Bindings>
<ce:BindingCollection>
<Binding Path="RoundLeft" />
<Binding Path="RoundRight" />
</ce:BindingCollection>
</ce:MultiBinding.Bindings>
</ce:MultiBinding>
</ce:MultiBindings>
</Border>
Here’s my converter, although the execution never gets this far, i.e. my breakpoint is never hit.
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values.Length == 2 && values.All(v => v is bool))
{
var roundLeft = (bool)values[0];
var roundRight = (bool)values[1];
return new CornerRadius(
roundLeft ? 6 : 0,
roundRight ? 6 : 0,
roundRight ? 6 : 0,
roundLeft ? 6 : 0);
}
else
{
return new CornerRadius(6);
}
}
I implemented the approach @Foovanadil suggested, but then I got another idea: I created a new ContentControl that exposes RoundLeft and RoundRight dependency properties. It certainly involved more code, but now the CornerRadius stuff is all in the View layer.
Then I created a ControlTemplate for it (some properties omitted for brevity):
Then here’s where I bound it to the view-model properties: