属性
我正在尝试将Gauge fill属性的颜色绑定到我创建的代码后面的SolidColorBrush。它适用于progressbar,但不适用于Gauge。绑定可以工作,但它不会像progressbar那样自动更新。是否可以在不重新绘制的情况下更新它?谢谢
XAML:
<Grid Grid.Column="0">
<lvc:Gauge Grid.Row="2" Grid.Column="0" Margin="5"
From="0" To="{Binding Path=attaBitrateUP}" Value="{Binding Path=actBitrateUP}" GaugeActiveFill="{Binding Path=up, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
<Grid Grid.Row="2">
<StackPanel>
<TextBlock Text="Carrier count:" Height="20" VerticalAlignment="Bottom" Margin="10,0,0,5"/>
<ProgressBar Height="25" Margin="10,0,10,0" Value="{Binding Path=chartValuesUP}" Maximum="{Binding Path=chartValuesCount}" Foreground="{Binding Path=up}" Background="{Binding Path=down}"/>
</StackPanel>
</Grid>
代码隐藏:
private SolidColorBrush _up = new SolidColorBrush(Colors.OrangeRed);
public SolidColorBrush up
{
get { return _up; }
set
{
_up = value;
NotifyPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
GaugeActiveFill
没有注册属性更改回调。因此,在调用数据绑定时,它不会检测到更改。坦率地说,图书馆的实施相当草率。
但我们可以通过扩展原始的Gauge
类来注册丢失的属性更改处理程序:来自己修复它
FixedGauge.cs
public class FixedGauge : Gauge
{
static FixedGauge()
{
GaugeActiveFillProperty.OverrideMetadata(typeof(FixedGauge), new FrameworkPropertyMetadata(default(Brush), OnGaugeActiveFillChanged));
}
private PieSlice PART_Pie { get; set; }
public FixedGauge()
{
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (TryFindVisualChildElementByName(this, null, out PieSlice pie))
{
this.PART_Pie = pie;
}
}
private static void OnGaugeActiveFillChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
=> (d as FixedGauge).OnGaugeActiveFillChanged(e.OldValue as Brush, e.NewValue as Brush);
protected virtual void OnGaugeActiveFillChanged(Brush oldBrush, Brush newBrush)
{
if (this.PART_Pie == null)
{
return;
}
this.PART_Pie.Fill = newBrush;
}
public static bool TryFindVisualChildElementByName<TChild>(
DependencyObject parent,
string childElementName,
out TChild resultElement) where TChild : FrameworkElement
{
resultElement = null;
if (parent is Popup popup)
{
parent = popup.Child;
if (parent == null)
{
return false;
}
}
for (var childIndex = 0; childIndex < VisualTreeHelper.GetChildrenCount(parent); childIndex++)
{
DependencyObject childElement = VisualTreeHelper.GetChild(parent, childIndex);
if (childElement is TChild frameworkElement)
{
if (string.IsNullOrWhiteSpace(childElementName) || frameworkElement.Name.Equals(
childElementName,
StringComparison.OrdinalIgnoreCase))
{
resultElement = frameworkElement;
return true;
}
}
if (TryFindVisualChildElementByName(childElement, childElementName, out resultElement))
{
return true;
}
}
return false;
}
}
然后使用这个新控件来代替原来的:
<local:FixedGauge Grid.Row="2" Grid.Column="0" Margin="5"
From="0" To="{Binding Path=attaBitrateUP}"
Value="{Binding Path=actBitrateUP}"
GaugeActiveFill="{Binding Path=up}" />