需求描述
某个ListView占据整个窗口,当窗口的宽度发生改变时,某一列中显示的、某一行的字符数目,能跟随窗口宽度变化而增减。
下面是我做完的效果:(只展示窗口的一部分)
此时是窗口缩放的极限,不能再小了。
 
 拖动窗口变大后,可以看到字符数目也变多了。
 
设计思路
首先,因为需要列出多行,选择使用ListView。使用固定宽度的单列(GridViewColumn),并将其宽度设为窗口实际宽度,可以实现占满窗口的效果。每当窗口的尺寸发生变化时,通过监听,可以及时重新绘制ListView。
至于刻度尺,主要是线段的组合。这里我自己写了一个Ruler控件,并增加一个RowBaseCnt属性,用这个属性控制刻度的数目。每次属性值变化时,刻度尺需要重新绘制。
最后,RowBaseCnt的计算用的是总宽度,扣除两侧元件的固定宽度,然后除以单个字符宽度计算而成。如果实现的效果有偏差,可以手动加一个倍数或者调边距。
实现
出于保密原因,这里不会放出完整代码。不完整的部分基本都可以自行补全或自行搜索。实在不懂请在搜索无果后,关注+私信。如果您的提问太简单,恕不回复。
固定宽度的ListView列
参考下面文章,可以直接copy。
https://blog.csdn.net/pxy7896/article/details/113174144
监听窗口尺寸变化
public MainWindow(){
	InitializeComponent();
	...
	this.SizeChanged += new SizeChangedEventHandler(MainWindow_Resize);
}
private void MainWindow_Resize(object sender, SizeChangedEventArgs e){
	...
}
 
刻度尺控件增加一个RowBaseCnt属性
Ruler是之前写过的一个自定义控件,代码就不贴了,xaml的结构大概是:
<UserControl>
    <Grid x:Name="x" HorizontalAlignment="Left">
    </Grid>
</UserControl>
 
后台用x.Children.Add(line)的方式绘制。主要是注意循环的边界,控制线条长度等,不再贴代码。需要的私信我留邮箱。
public partial class RowRuler : Ruler {
	public static readonly DependencyProperty RowBaseCntProperty =
		DependencyProperty.Register(
            "RowBaseCnt",
			typeof(int),
			typeof(RowRuler),
			new FrameworkPropertyMetadata(int.MinValue, new PropertyChangedCallback(OnRowBaseCntChanged))
            );
	private static void OnRowBaseCntChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) {
		RowRuler rr = sender as RowRuler;
		if (rr != null) {
			rr.OnValueChanged(args);
		}
	}
	protected void OnValueChanged(DependencyPropertyChangedEventArgs args) { 
		this.RowBaseCnt = (int)args.NewValue;
		// 这里表示每次修改RowBaseCnt时都重新绘制RowRuler
		draw();
	}
	public int RowBaseCnt
	{
		get { return (int)GetValue(RowBaseCntProperty); }
		set { SetValue(RowBaseCntProperty, value); }
	}
	
	public void draw(){
		// 这里写具体的绘制代码
	}
	
}
 
字符宽度计算
public static double MeasureTextWidth(string text, double fontSize, string fontFamily)
{
    FormattedText formattedText = new FormattedText(
    text,
    System.Globalization.CultureInfo.InvariantCulture,
    FlowDirection.LeftToRight,
    new Typeface(fontFamily.ToString()),
    fontSize,
    Brushes.Black
    );
    return formattedText.WidthIncludingTrailingWhitespace;
}
 
这里为了方便,我直接用了"Courier New"。








![[附源码]JAVA毕业设计同学录网站(系统+LW)](https://img-blog.csdnimg.cn/67e16762aec247308de0dc570c235d09.png)

![[ MySQL ] 使用Navicat进行MySQL数据库备份 / 还原(备份.nb3文件方式)](https://img-blog.csdnimg.cn/df24e9b7c2be46bb85f4c133c29cd6db.png)







