如何在包含控件的 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 方法并手动创建展开按钮。我认为学习使用库是正确的方法,但最终我认为我真正的问题是,为什么滚动查看器不更新内部控件的大小。制作自定义滚动条以在调整大小时更新其内容的正确解决方案?