在 CustomControl 中绑定 ProgressBar 似乎不起作用
Binding ProgressBar in CustomControl seems not to work
我得到了一个包含 ProgressBar 和其他元素的自定义控件。
<ProgressBar Value="{TemplateBinding CurrentProgress}"
MinValue="{TemplateBinding MinValue}"
MaxValue="{TemplateBinding MaxValue}"/>
<Label Content="{TemplateBinding CurrentProgress}"/>
在我的 .cs 文件中,我定义了所有这些属性,如下所示:
#region MaxProgress
public int MaxProgress
{
get { return (int)GetValue(MaxProgressProperty); }
set { SetValue(MaxProgressProperty, value); }
}
public static readonly DependencyProperty MaxProgressProperty =
DependencyProperty.Register("MaxProgress", typeof(int), typeof(GameFlowControl), new FrameworkPropertyMetadata(1000, FrameworkPropertyMetadataOptions.AffectsRender));
#endregion
#region CurrentProgress
public int CurrentProgress
{
get { return (int)GetValue(CurrentProgressProperty); }
set { SetValue(CurrentProgressProperty, value); }
}
public static readonly DependencyProperty CurrentProgressProperty =
DependencyProperty.Register("CurrentProgress", typeof(int), typeof(GameFlowControl), new FrameworkPropertyMetadata(50, FrameworkPropertyMetadataOptions.AffectsRender));
#endregion
#region MinProgress
public int MinProgress
{
get { return (int)GetValue(MinProgressProperty); }
set { SetValue(MinProgressProperty, value); }
}
public static readonly DependencyProperty MinProgressProperty =
DependencyProperty.Register("MinProgress", typeof(int), typeof(GameFlowControl), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
#endregion
如上所示将这些值绑定到标签工作正常,但显然这些绑定不适用于我的 ProgressBar。到目前为止我尝试了什么:
- 更改值、最小值和最大值的顺序。
- 在 TemplateBinding 中添加了一个拼写错误(如 CurrentProgressXYZ),这给了我一个编译错误(所以属性被识别)
- 为属性添加了默认值(参见 0、50、1000)。
- 直接删除了绑定和设置值:Value = 50,MinValue = 0,MaxValue = 100,显示 ProgressBar 显示为半满。
- 为这些属性的 getter 添加了断点,它们未触发(这让我很困惑!)
任何可能导致此问题的提示?
根据你的问题回答
在这种情况下您应该使用的绑定方法是Value="{Binding CurrentProgress, RelativeSource={RelativeSource AncestorType={x:Type GameFlowControl}}}"
。这将向上遍历可视化树找到第一个 GameFlowControl
控件,然后从该相对位置绑定到路径。
另一种选择
作为替代方案,如果您不将 UserControl
中的 DataContext
用于任何其他目的,您可以使用较短的绑定方法。
首先,您需要使用如下方式将 DataContext
分配给派生的 UserControl
引用:-
public GasFlowControl()
{
InitializeComponent();
DataContext = this; //Set the DataContext to point to the control itself
}
那么您的绑定可以简化为:-
<ProgressBar Value="{Binding CurrentProgress}"
MinValue="{Binding MinValue}"
MaxValue="{Binding MaxValue}"/>
<Label Content="{Binding CurrentProgress}"/>
解答你的困惑
Added Breakpoints to the getters of those properties, they were not triggered (which confuses me a lot!)
您没有为 属性 Getters 和 Setters 触发任何断点的原因是 WPF 框架不使用它们。它在内部直接调用 GetValue(CurrentProgressProperty);
和 SetValue(CurrentProgressProperty, value);
。它们的存在只是为了方便您将其包含在您的代码中,并具有类型转换的便利性,从而在编译时进行类型检查。
如果您的代码不使用它们,那么它们将永远不会被调用。
我得到了一个包含 ProgressBar 和其他元素的自定义控件。
<ProgressBar Value="{TemplateBinding CurrentProgress}"
MinValue="{TemplateBinding MinValue}"
MaxValue="{TemplateBinding MaxValue}"/>
<Label Content="{TemplateBinding CurrentProgress}"/>
在我的 .cs 文件中,我定义了所有这些属性,如下所示:
#region MaxProgress
public int MaxProgress
{
get { return (int)GetValue(MaxProgressProperty); }
set { SetValue(MaxProgressProperty, value); }
}
public static readonly DependencyProperty MaxProgressProperty =
DependencyProperty.Register("MaxProgress", typeof(int), typeof(GameFlowControl), new FrameworkPropertyMetadata(1000, FrameworkPropertyMetadataOptions.AffectsRender));
#endregion
#region CurrentProgress
public int CurrentProgress
{
get { return (int)GetValue(CurrentProgressProperty); }
set { SetValue(CurrentProgressProperty, value); }
}
public static readonly DependencyProperty CurrentProgressProperty =
DependencyProperty.Register("CurrentProgress", typeof(int), typeof(GameFlowControl), new FrameworkPropertyMetadata(50, FrameworkPropertyMetadataOptions.AffectsRender));
#endregion
#region MinProgress
public int MinProgress
{
get { return (int)GetValue(MinProgressProperty); }
set { SetValue(MinProgressProperty, value); }
}
public static readonly DependencyProperty MinProgressProperty =
DependencyProperty.Register("MinProgress", typeof(int), typeof(GameFlowControl), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
#endregion
如上所示将这些值绑定到标签工作正常,但显然这些绑定不适用于我的 ProgressBar。到目前为止我尝试了什么:
- 更改值、最小值和最大值的顺序。
- 在 TemplateBinding 中添加了一个拼写错误(如 CurrentProgressXYZ),这给了我一个编译错误(所以属性被识别)
- 为属性添加了默认值(参见 0、50、1000)。
- 直接删除了绑定和设置值:Value = 50,MinValue = 0,MaxValue = 100,显示 ProgressBar 显示为半满。
- 为这些属性的 getter 添加了断点,它们未触发(这让我很困惑!)
任何可能导致此问题的提示?
根据你的问题回答
在这种情况下您应该使用的绑定方法是Value="{Binding CurrentProgress, RelativeSource={RelativeSource AncestorType={x:Type GameFlowControl}}}"
。这将向上遍历可视化树找到第一个 GameFlowControl
控件,然后从该相对位置绑定到路径。
另一种选择
作为替代方案,如果您不将 UserControl
中的 DataContext
用于任何其他目的,您可以使用较短的绑定方法。
首先,您需要使用如下方式将 DataContext
分配给派生的 UserControl
引用:-
public GasFlowControl()
{
InitializeComponent();
DataContext = this; //Set the DataContext to point to the control itself
}
那么您的绑定可以简化为:-
<ProgressBar Value="{Binding CurrentProgress}"
MinValue="{Binding MinValue}"
MaxValue="{Binding MaxValue}"/>
<Label Content="{Binding CurrentProgress}"/>
解答你的困惑
Added Breakpoints to the getters of those properties, they were not triggered (which confuses me a lot!)
您没有为 属性 Getters 和 Setters 触发任何断点的原因是 WPF 框架不使用它们。它在内部直接调用 GetValue(CurrentProgressProperty);
和 SetValue(CurrentProgressProperty, value);
。它们的存在只是为了方便您将其包含在您的代码中,并具有类型转换的便利性,从而在编译时进行类型检查。
如果您的代码不使用它们,那么它们将永远不会被调用。