WPF随笔之 控件根据设定的显示行数列数填充控件并自适应窗体大小(多绑定MVVM方式实现)

(效果图,如见最下面)

需求:根据设置的行数列数,控制展示控件个数,并且填充的控件们大小刚刚好自适应填充满固定的区域,并且调整窗体大小的时候控件动态自适应窗体大小,即自适应大小并不显示滚动条(比如,设置了1行1列,则第一页显示一个控件,如设置了2行2列,则第一页显示第一行2个控件,第二行2个控件)。

解决方案,我总结有3

1.在cs代码里面动态生成Grid控件,根据设定的行列动态生成行列,将控件自适应宽高填充进去

2.固定Grid。使用WrapPanel排序,当Grid实际宽高发生改变时,动态计算每一个格子控件的宽高,通过绑定每一个控件的宽高实现

3.使用MVVM方式,利用Converter实现

其实第一第二种都特别winform写法,当年做MVC的时候,已经被MVC的模式洗脑,自己万不得已的时候才会使用这两种方式去实现,所以不推荐大家使用

当接手这个功能的时候已经有人使用方法2实现,在绑定的实体里面加了三个属性,FontSize、Width、Height,而且计算也不准确,忽略了margin,最小值设定等东西。(耦合性强,代码错乱,不好维护等缺点不一一列举),现在改成方式3去实现,特别简单,我们只需要使用Converter实现就好,因为ConverterParameter并不支持Binding写法,这里需用用到了多绑定方式去实现

(代码仅做参考,异常处理未写)

<ItemsControl Grid.Row="1"  x:Name="list" ItemsSource="{Binding DefectCodeInfoPage}"  >
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel  IsItemsHost="True"/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <!--高度应设最小值-->
                                    <Grid Margin="0 5 5 5" MinHeight="30">
                                        <Grid.Width>
                                            <MultiBinding Converter="{StaticResource WidthConverter}">
                                                <Binding ElementName="list" Path="ActualWidth" />
                                                <Binding Path="DataContext.Colunm" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ModPqcHeaderAdd}}"/>
                                                <Binding Path="Margin" RelativeSource="{RelativeSource Mode=Self}" />
                                            </MultiBinding>
                                        </Grid.Width>
                                        <Grid.Height>
                                            <MultiBinding Converter="{StaticResource HeightConverter}">
                                                <Binding ElementName="list" Path="ActualHeight" />
                                                <Binding Path="DataContext.Row" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ModPqcHeaderAdd}}"/>
                                                <Binding Path="Margin" RelativeSource="{RelativeSource Mode=Self}" />
                                            </MultiBinding>
                                        </Grid.Height>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="7*" />
                                        <ColumnDefinition Width="3*" />
                                        </Grid.ColumnDefinitions>
                                        <Button
                                            Grid.Column="0"
                                            HorizontalAlignment="Stretch"
                                            VerticalAlignment="Stretch"
                                            Width="auto"
                                            Height="auto"
                                            Click="Button_MouseDown"
                                            Content="{Binding DEFECT_CODE_NAME, Mode=TwoWay}"
                                            FontFamily="Microsoft YaHei"
                                            FontSize="{Binding FontSize}"
                                            Foreground="Black"
                                            FontWeight="Bold"
                                            Tag="{Binding DEFECT_CODE, Mode=TwoWay}" />

                                        <TextBox
                                            Grid.Column="1"
                                            Width="auto"
                                            Height="auto"
                                            HorizontalAlignment="Stretch"
                                            VerticalAlignment="Stretch"
                                            HorizontalContentAlignment="Center"
                                            VerticalContentAlignment="Center"
                                            FontFamily="Microsoft YaHei"
                                            FontSize="{Binding FontSize}"
                                            Text="{Binding QTY, Mode=TwoWay}"
                                            TextAlignment="Center" />
                                    </Grid>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>

部分代码xaml

多绑定的Converter实现如下

 1     [ValueConversion(typeof(double), typeof(double))]
 2     public class WidthConverter : IMultiValueConverter
 3     {
 4         public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
 5         {
 6             double intWidth = 100;
 7             try
 8             {
 9
10                 double actualWidth = (double)value[0];
11                 int cols = System.Convert.ToInt32(value[1]);
12                 Thickness margin = (Thickness)(value[2]);
13                 double lmargin = margin.Left;
14                 double rmargin = margin.Right;
15
16                 if (cols == 0)
17                     return cols = 1;
18
19                 intWidth = actualWidth / cols - cols * (lmargin + rmargin);
20             }
21             catch(Exception ex)
22             {
23             }
24             return intWidth;
25
26         }
27         public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
28         {
29             return null;
30
31         }
32
33     }
34
35     [ValueConversion(typeof(double), typeof(double))]
36     public class HeightConverter : IMultiValueConverter
37     {
38
39         public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
40         {
41             double intHeight = 30;
42             try
43             {
44
45                 double actualHeight = (double)value[0];
46                 int rows = System.Convert.ToInt32(value[1]);
47                 Thickness margin = (Thickness)(value[2]);
48                 double tmargin = margin.Top;
49                 double bmargin = margin.Bottom;
50                 if (rows == 0)
51                     rows = 1;
52                 intHeight = actualHeight / rows - rows * (tmargin + bmargin);
53             }
54             catch
55             {
56             }
57             return intHeight;
58
59         }
60         public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
61         {
62             return null;
63
64         }
65
66     }

Converters.cs

当当当当~~~~ 是不是超简单,超简洁的。这样根本不用写一堆属性,还在各处去控制它们,总而言之一句话,“术业有专攻”,前台的东西莫要带走

设置一列一行时

设置两行一列时

设置一行两列时

设置N行N列时(忽略不截图了)

原文地址:https://www.cnblogs.com/cactis/p/8718545.html

时间: 2024-10-10 18:19:53

WPF随笔之 控件根据设定的显示行数列数填充控件并自适应窗体大小(多绑定MVVM方式实现)的相关文章

iOS 随笔小技巧 弱self 打印当前类行数列数,多人开发自动适配pch地址,获取设备uid的信息

$(SRCROOT)/PrefixHeader.pch自动适配pch地址 __weak __block typeof(self) weakself = self; __weak typeof(self)weakSelf = self; #define DN_DEBUG_LOG(fmt, ...) {NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); } NSDictionary *if

如何让窗体大小随着控件的大小变化而变化

form的autosize=true,formborderstyle=fixedsingle tablelayoutpanel及其里面的容器的dock=fill,autosize=true label中的文字比较贴着窗体边缘时可以通过padding属性来调整 因定宽度则可以使用tablelayoutpanel中的列固定 atablelayoutpanel中的行也可以固定,而不固定行直接按百分比来设置 如何让窗体大小随着控件的大小变化而变化

vc中实现控件的隐藏与显示

1.隐藏控件 CWnd *pWnd; pWnd = GetDlgItem(IDC_EDIT1);        //获取控件指针,IDC_EDIT1为控件ID号         pWnd->ShowWindow( SW_HIDE );      //隐藏控件 2.显示控件 CWnd *pWnd;         pWnd = GetDlgItem( IDC_EDIT1 );   //获取控件指针,IDC_EDIT为控件ID号        pWnd->ShowWindow( SW_SHOW )

wpf随笔

因项目需要查找wpf.DataGrid的Binding方法, 由于其属于Dev框架体系内,偏向于winform并无Binding 1.且线程外更改UI控件还需要委托或者action,而Wpf控件仅需要binding后,数据源修改界面控件无论是在线程内外均不受影响 2.更改数据源wpf.DataGrid也必须通过静态方法,对实例化后的页面控件进行操作,并且对数据操作前后需要BeginDataUpdate与EndDataUpdate 而WPF则不需要,直接对数据源进行修改即可

七:理解控件的运行机制(例:基于CompositeControl命名空间的控件)

组合控件与WebControl控件的事件和属性相差不大组合控件,顾名思义就是把一些控件组合起来形成一个控件这个控件将包含这些控件称为他的子控件 CompositeControl类实现了INameContainer接口这样使得复合控件下的子控件都根据各自的层级关系生成唯一的客户端标识不至于产生重复的ID 组合控件比较重要的方法是:1.EnsureChildControls此方法判断属性ChildControlsCreated是否为true如果不是将执行下面的事件2.CreateChildContr

atitit. 浏览器插件 控件 applet 的部署,签名总结 浏览器 插件 控件 的签名安全机制o9o

atitit. 浏览器插件 控件   applet 的部署,签名总结 浏览器 插件 控件 的签名安全机制o9o 1. 服务器部署签名 1 2. 签名流程::生成密钥..导出cert正书,签名 1 3. jarsigner 错误: java.lang.IllegalArgumentException: MALFORMED 1 4. Jar的包装and签名的流程原理 2 5. 参考 2 1. 服务器部署签名 applet 的本地调试,可以使用调整java.policy的解决...虽然中间也能正式版使

重新想象 Windows 8.1 Store Apps (77) - 控件增强: 文本类控件的增强, 部分控件增加了 Header 属性和 HeaderTemplate 属性, 部分控件增加了 PlaceholderText 属性

[源码下载] 重新想象 Windows 8.1 Store Apps (77) - 控件增强: 文本类控件的增强, 部分控件增加了 Header 属性和 HeaderTemplate 属性, 部分控件增加了 PlaceholderText 属性 作者:webabcd介绍重新想象 Windows 8.1 Store Apps 之控件增强 文本类控件的增强 为一些控件增加了 Header 属性和 HeaderTemplate 属性 为一些控件增加了 PlaceholderText 属性 示例1.演示

【转】PropertyGrid控件中的多级显示

运行效果: 解决方案: MainForm.cs public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { CProvincialCapital proCap = new CProvincialCapital("南京市", 10000000); CProvince pro

在控件的任意位置显示图片

在控件的任意位置显示图片 效果图 xml代码 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent&