在 BorderThinkness 中将 int 属性 与 StringFormat 绑定
Bind int property with StringFormat in BorderThinkness
我有一个带有自己的 属性 边框宽度的模板:
public static readonly DependencyProperty BorderWidthProperty = DependencyProperty.Register("BorderWidth", typeof(int), typeof(ProjectOverviewSensor), new PropertyMetadata(1));
现在我想在我的模板中使用 StringFormat 将此 属性 绑定到 BorderThickness 以创建特定边的边框。但是它在所有四个方面都是1。
<Border BorderThickness="{Binding Path=BorderWidth, RelativeSource={RelativeSource TemplatedParent}, StringFormat='{}{0},0,{0},0'}"></Border>
我如何才能将 属性 绑定到我想要的边界控制的两侧?是否有字符串格式的替代方法?
Binding.StringFormat
仅适用于 System.String
类型的属性。
用XAML写的字符串就不同了,因为在这里,XAML解析器在解析过程中将字符串转换为粗细值。
要执行您想要的操作,您需要绑定一个转换器:
class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == DependencyProperty.UnsetValue)
return value;
return new Thickness((int)value,0, (int)value, 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((Thickness)value).Left;
}
}
并像这样使用:
<Window.Resources>
<MyConverter x:Key="ToThickness"/>
</Window.Resources>
<Border BorderThickness="{Binding Path=BorderWidth, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ToThickness}"></Border>
现在我创建了一个扩展转换器,我希望他不要对你隐瞒。
public class CustomThicknessConverter : IValueConverter
{
protected readonly char SplitChar = ',';
protected readonly char ReplaceAt = '#';
/// <summary>
/// Create a thickness with custom format(for example #,2,#,5).
/// </summary>
/// Number for default width.
/// # for given border width.
/// ; for split the chars.
/// For example '#,0,#,0' with 1 as value return a new thickness
/// with Left = 1, Top = 0, Right = 1, Bottom = 0.
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == DependencyProperty.UnsetValue)
return value;
var borderWidth = value as double?;
var format = parameter.ToString().Split(SplitChar);
if(format.Length == 1)
return new Thickness(GetValue(borderWidth, format[0]));
else if(format.Length == 2)
{
return new Thickness()
{
Left = GetValue(borderWidth, format[0]),
Top = GetValue(borderWidth, format[1]),
Right = GetValue(borderWidth, format[0]),
Bottom = GetValue(borderWidth, format[1])
};
}
else if(format.Length == 4)
{
return new Thickness()
{
Left = GetValue(borderWidth, format[0]),
Top = GetValue(borderWidth, format[1]),
Right = GetValue(borderWidth, format[2]),
Bottom = GetValue(borderWidth, format[3])
};
}
return new Thickness(0);
}
private double GetValue(double? value, string format)
{
if(format.FirstOrDefault() == ReplaceAt) return value ?? 0;
double result;
return (Double.TryParse(format, out result)) ? result : 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
在xaml中:
<local:CustomThicknessConverter x:Key="CustomThicknessConverter" />
<Border BorderThickness="{Binding BorderWidth, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource CustomThicknessConverter}, ConverterParameter='0,#,0,#'}">
</Border>
我有一个带有自己的 属性 边框宽度的模板:
public static readonly DependencyProperty BorderWidthProperty = DependencyProperty.Register("BorderWidth", typeof(int), typeof(ProjectOverviewSensor), new PropertyMetadata(1));
现在我想在我的模板中使用 StringFormat 将此 属性 绑定到 BorderThickness 以创建特定边的边框。但是它在所有四个方面都是1。
<Border BorderThickness="{Binding Path=BorderWidth, RelativeSource={RelativeSource TemplatedParent}, StringFormat='{}{0},0,{0},0'}"></Border>
我如何才能将 属性 绑定到我想要的边界控制的两侧?是否有字符串格式的替代方法?
Binding.StringFormat
仅适用于 System.String
类型的属性。
用XAML写的字符串就不同了,因为在这里,XAML解析器在解析过程中将字符串转换为粗细值。
要执行您想要的操作,您需要绑定一个转换器:
class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == DependencyProperty.UnsetValue)
return value;
return new Thickness((int)value,0, (int)value, 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((Thickness)value).Left;
}
}
并像这样使用:
<Window.Resources>
<MyConverter x:Key="ToThickness"/>
</Window.Resources>
<Border BorderThickness="{Binding Path=BorderWidth, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ToThickness}"></Border>
现在我创建了一个扩展转换器,我希望他不要对你隐瞒。
public class CustomThicknessConverter : IValueConverter
{
protected readonly char SplitChar = ',';
protected readonly char ReplaceAt = '#';
/// <summary>
/// Create a thickness with custom format(for example #,2,#,5).
/// </summary>
/// Number for default width.
/// # for given border width.
/// ; for split the chars.
/// For example '#,0,#,0' with 1 as value return a new thickness
/// with Left = 1, Top = 0, Right = 1, Bottom = 0.
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == DependencyProperty.UnsetValue)
return value;
var borderWidth = value as double?;
var format = parameter.ToString().Split(SplitChar);
if(format.Length == 1)
return new Thickness(GetValue(borderWidth, format[0]));
else if(format.Length == 2)
{
return new Thickness()
{
Left = GetValue(borderWidth, format[0]),
Top = GetValue(borderWidth, format[1]),
Right = GetValue(borderWidth, format[0]),
Bottom = GetValue(borderWidth, format[1])
};
}
else if(format.Length == 4)
{
return new Thickness()
{
Left = GetValue(borderWidth, format[0]),
Top = GetValue(borderWidth, format[1]),
Right = GetValue(borderWidth, format[2]),
Bottom = GetValue(borderWidth, format[3])
};
}
return new Thickness(0);
}
private double GetValue(double? value, string format)
{
if(format.FirstOrDefault() == ReplaceAt) return value ?? 0;
double result;
return (Double.TryParse(format, out result)) ? result : 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
在xaml中:
<local:CustomThicknessConverter x:Key="CustomThicknessConverter" />
<Border BorderThickness="{Binding BorderWidth, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource CustomThicknessConverter}, ConverterParameter='0,#,0,#'}">
</Border>