0

如何在包含控件的 sizechanged 事件上更新由 itemtemplate 制作的树视图项目?

我以为我会从 itemcontainergenerator 中获取容器并在 headertemplate 中搜索控件。但是,由于未应用标题模板,我收到错误消息。

 private void SignalBox_SizeChanged(object sender, SizeChangedEventArgs e)
    {
      if (e.WidthChanged)
      {
        double change_in_width = e.NewSize.Width - e.PreviousSize.Width;
        signal_graph_window_width = ActualWidth - NamePanelWidth;
        TreeView tv = this.signal_treeview_item_control;
        foreach (var item in tv.Items)
        {
          TreeViewItem container = tv.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
          if (container != null && container.HeaderTemplate.Is)
          {
            SignalGraph sg = container.HeaderTemplate.FindName("signal_graph", container) as SignalGraph;

我阅读了有关该主题的更多内容,似乎我得到的错误是因为尚未应用模板。我读到的大多数答案都建议将事件处理程序绑定到 onapplytemplate,但我不能只对 onapplytemplate 事件做出反应,或者大小可能没有改变。

我希望我的信号图能够根据可用大小进行绘制,并在窗口大小发生变化时重新绘制和更新。

编辑:一张海报暗示我做错了。可能是真的,但我不知道该怎么做。

我有一个自定义用户控件“signal_box”,并且我有一个属性“signal_graph_window_width”,它绑定到 signal_box 的子 FrameworkElement 信号图。

signalgraph 需要两个属性来绘制图形,signal_graph_window_width 和信号图的宽度。前者是窗口有多少实际空间,由 window.actualwidth - signalnamepanel.width 计算得出。后者决定了实际需要绘制多少数据。

信号图被包裹在一个网格中,该网格被包裹在一个滚动查看器中,因此如果有更多的数据无法在屏幕上显示,您可以滚动查看其余部分。我只想将滚动查看器放在包含信号图的网格部分,以便在滚动时信号名保持可见。

最初我让信号箱在调整大小时手动修改信号图。这是在代码隐藏中完成的,通过在 ItemsControl 的 itemtemplate 中找到具有正确名称的控件来更新信号图的宽度。

当我有一个 itemcollection 时,这一切都很好,但后来我决定使用树视图,这样我就可以扩展实际的信号。不幸的是,抓取模板化 itemcontrol 的代码隐藏修改不再适用于新的树视图模板。

现在在我看来,解决方案就是弄清楚如何访问此处定义的正确控件:

<TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource ="{Binding Path = bits}">
      <Grid x:Name="signal_box_grid" Background="Black">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="200"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <wpfExp:SignalNamePanel Grid.Column="0"
            Height="{Binding ElementName=signal_box, Path=GraphHeight, Mode=OneWay}"
            x:Name="signal_name_panel"
            MainText="{Binding Path = SignalName}" 
          />
        <wpfExp:SignalGraph Grid.Column="1"
            x:Name="signal_graph"
            IsSignal="True"
            Height="{Binding ElementName=signal_box, Path=GraphHeight, Mode=OneWay}"
            PenWidth="{Binding ElementName=signal_box, Path=GraphPenWidth, Mode=OneWay}"
            Signal="{Binding}" 
            signal_graph_window_width="{Binding ElementName=signal_box, Path=signal_graph_window_width, Mode=OneWay}"
            X_Scale="{Binding ElementName=signal_box, Path=X_Scale, Mode=OneWay}"
            MaxTimeValue="{Binding RelativeSource = {RelativeSource AncestorType={x:Type wpfExp:SignalBox}}, Path = _SignalData.MaxTimeValue}"
          />
      </Grid>


      <HierarchicalDataTemplate.ItemTemplate>
            <DataTemplate>
              <Grid Background="Black">
                <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="200"/>
                  <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <wpfExp:SignalNamePanel Grid.Column="0"
                Height="{Binding ElementName=signal_box, Path=GraphHeight, Mode=OneWay}"
                x:Name="signal_name_panel"
                MainText="{Binding Path = BitNumber}" 
              />
                <wpfExp:SignalGraph Grid.Column="1"
                x:Name="signal_graph"
                IsSignal="False"
                Height="{Binding ElementName=signal_box, Path=GraphHeight, Mode=OneWay}"
                PenWidth="{Binding ElementName=signal_box, Path=GraphPenWidth, Mode=OneWay}"
                Bit="{Binding}" 
                signal_graph_window_width="{Binding ElementName=signal_box, Path=signal_graph_window_width, Mode=OneWay}"
                X_Scale="{Binding ElementName=signal_box, Path=X_Scale, Mode=OneWay}"
                MaxTimeValue="{Binding RelativeSource = {RelativeSource AncestorType={x:Type wpfExp:SignalBox}}, Path = _SignalData.MaxTimeValue}"
              />
              </Grid>
            </DataTemplate>
          </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
      </TreeView.ItemTemplate>

但也许我只是做错了。

我想根据 Sizechanged 修改图形宽度的原因是,当用户调整窗口大小超出信号的绘制长度时,我想重新绘制信号并将其扩展到窗口的末尾。

从这里可以看出,当我调整大小时,信号没有被重绘到屏幕的末尾。我应该如何让 signalgraph 知道它需要绘制更多内容才能到达屏幕末尾?

http://picpaste.com/signalgraph2-oObkPXLX.JPG

我有一个视图模型

   public class SignalDataViewModel
  {
    ObservableCollection<SignalViewModel> _signals;
    public ObservableCollection<SignalViewModel> Signals
    {
      get
      {
        return _signals;
      }
      private set
      {
        _signals = value;
      }
    }

    SignalData signal_data;

接受 signaldata 和 signaldata 包含可观察的信号集合:

 public ObservableCollection<Signal> list_of_signals
    {
      get;
      set;
    }

看起来像这样:

public class Signal
  {
    public bool isBus
    {
      get;
      private set;
    }
    public List<KeyValuePair<int, IList<byte>>> SignalValues
    {
      get;
      private set;
    }
    public List<KeyValuePair<int, string>> HexSignalValues
    {
      get;
      private set;
    }
    public string SignalName
    {
      get;
      private set;
    }
    public Signal(string name, bool isBus)
    {
      SignalValues = new List<KeyValuePair<int, IList<byte>>>();
      this.SignalName = name;
      this.isBus = isBus;
    }

我一直想知道我是否最好只使用以前的 itemscontrol 方法并手动创建展开按钮。我认为学习使用库是正确的方法,但最终我认为我真正的问题是,为什么滚动查看器不更新内部控件的大小。制作自定义滚动条以在调整大小时更新其内容的正确解决方案?

4

1 回答 1

0

所以我终于想出了如何避免手动调用孩子和男孩的控件,代码看起来更干净。基本上问题是我需要为我的框架元素覆盖 MeasureOverride 以及更改我的绑定属性以具有影响测量元数据选项。

public double signal_graph_window_width
    {
      get { return (double)GetValue(signal_graph_window_width_property); }
      set
      {
        SetValue(signal_graph_window_width_property, value);
      }
    }
    public static readonly DependencyProperty signal_graph_window_width_property =
      DependencyProperty.Register("signal_graph_window_width",
      typeof(double), typeof(SignalGraph),
      new FrameworkPropertyMetadata(new double(), FrameworkPropertyMetadataOptions.AffectsMeasure));

通过正确覆盖度量,框架元素的大小得到更新,因此我可以将一个事件处理程序附加到框架元素上的 sizechanged 以强制重绘。

于 2013-06-26T23:53:38.850 回答