3

所以我有一个无法正确绑定的树视图样式。我已将高度绑定到使用该样式的用户控件的图形高度属性。但是,由于某些未知原因,它找不到用户控件。我希望有人可以对这个问题有所了解。是否禁止将模板的属性绑定到模板化父对象以外的东西?为什么它不能仅仅因为它在样式中就找不到元素。

从 xaml 文件的开头:

<UserControl 
  x:Class="WpfExperimental.GraphViewer"
  x:Name="graph_viewer"

然后是样式:

   <Style x:Key="SignalNameTreeViewStyle" TargetType="TreeView">
      <Setter Property="OverridesDefaultStyle" Value="True" />
      <Setter Property="SnapsToDevicePixels" Value="True" />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="TreeView">
            <ScrollViewer x:Name="SignalNameTreeView_ScrollViewer" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden">
              <StackPanel>
                <wpfExp:SignalNameBox x:Name="TreeViewTimeTextBox" Grid.Row="0" Grid.Column="0"
                      Height="{Binding ElementName=graph_viewer, Path=GraphHeight, Mode=OneWay}"
                      Width="200"
                      Margin="19,0,0,0"
                      MainText="Time" 
                    />
                <ItemsPresenter/>
              </StackPanel>         
            </ScrollViewer>
            <ControlTemplate.Triggers>
              <Trigger Property="ItemsControl.HasItems" Value="False">
                <Setter TargetName="TreeViewTimeTextBox"
                        Property="Visibility"
                        Value="Collapsed"/>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>

目前我从这次绑定尝试中得到数据绑定错误

ystem.Windows.Data Error: 39 : BindingExpression path error: 'GraphHeight' property not found on 'object' ''UserControl' (Name='graph_viewer')'. BindingExpression:Path=GraphHeight; DataItem='UserControl' (Name='graph_viewer'); target element is 'SignalNameBox' (Name='TreeViewTimeTextBox'); target property is 'Height' (type 'Double')
System.Windows.Data Error: 39 : BindingExpression path error: 'GraphHeight' property not found on 'object' ''UserControl' (Name='graph_viewer')'. BindingExpression:Path=GraphHeight; DataItem='UserControl' (Name='graph_viewer'); target element is 'SignalGraphAxis' (Name='signal_axis'); target property is 'GraphHeight' (type 'Int32')
System.Windows.Data Error: 39 : BindingExpression path error: '_SignalDataViewModel' property not found on 'object' ''UserControl' (Name='graph_viewer')'. BindingExpression:Path=_SignalDataViewModel.MaxTimeValue; DataItem='UserControl' (Name='graph_viewer'); target element is 'SignalGraphAxis' (Name='signal_axis'); target property is 'MaxTimeValue' (type 'Int32')
4

1 回答 1

2

我很确定您不能ElementName用来引用控件模板之外的元素。(尽管我现在找不到与此相关的文档。)即使可以,它也没有任何意义——您正在尝试编写包含隐藏依赖项的样式,这将引入潜在的运行时错误。

另一种方法是向控件添加依赖属性。编写一个扩展类TreeView,并给它一个命名SignalNameBoxHeight或类似的 DP。

public class ExtendedTreeView : TreeView
{
    public double SignalNameBoxHeight
    {
        get { return (double)GetValue(SignalNameBoxHeightProperty ); }
        set { SetValue(SignalNameBoxHeightProperty, value); }
    }

    public static readonly DependencyProperty SignalNameBoxHeightProperty =
        DependencyProperty.Register("SignalNameBoxHeight", 
        typeof(double), 
        typeof(ExtendedTreeView), 
        null);

    public ExtendedTreeView ()
    {
        this.DefaultStyleKey = typeof(Treeview);
    }
}

然后您可以TemplateBinding在控件模板内部使用来设置属性:

<wpfExp:SignalNameBox
    `Height="{TemplateBinding SignalNameBoxHeight}"`
/>

剩下的就是为您的风格的消费者提供绑定源:

<my:ExtendedTreeView 
    SignalNameBoxHeight="{Binding ElementName=graph_viewer, Path=GraphHeight}" />

编辑

看起来您可以FindAncestor用来引用控件模板之外的元素

{RelativeSource FindAncestor} 主要用于控件模板或可预测的自包含 UI 组合中,用于始终期望控件位于某个祖先类型的可视化树中的情况。

当然,限制是这仅适用于控件的祖先,而不是兄弟姐妹。

于 2013-07-12T21:47:38.360 回答