1. 程式人生 > 其它 >WPF通過DataTable繫結主從表及顯示修改進度條值

WPF通過DataTable繫結主從表及顯示修改進度條值

WPF在做這方面其實倒是比WINFORM要簡單太多

以下為程式碼

介面程式碼

<Window x:Class="MainViews.MatsterGrid"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:g="clr-namespace:GeneralTool.General.WPFHelper.Extensions;assembly=GeneralTool.General"
        mc:Ignorable="d"
        Title="MatsterGrid"
        Height="450"
        Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Menu>
            <MenuItem Header="Random"
                      Command="{Binding RandomCommand}"
                      CommandParameter="{Binding ElementName=Dg,Path=SelectedValue}"/>
        </Menu>
        <DataGrid x:Name="Dg"
                  g:NameDependency.Name="{g:Name ViewGrid}"
                  CanUserDeleteRows="False"
                  AutoGenerateColumns="False"
                  CanUserAddRows="False"
                  DataContext="{Binding}"
                  ItemsSource="{Binding Table}"
                  Grid.Row="1">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Content="{Binding Icon}"
                                    Command="{Binding ElementName=Dg,Path=DataContext.RowDetailCommand}" 
                                    CommandParameter="{Binding}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTextColumn Header="Value"
                                    Binding="{Binding Value}" 
                                    IsReadOnly="True"/>

                <DataGridTemplateColumn Header="Progress">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ProgressBar Value="{Binding Progress}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

            </DataGrid.Columns>

            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <DataGrid ItemsSource="{Binding SubTable}"
                              AutoGenerateColumns="False"
                              CanUserAddRows="False">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="ID"
                                                Binding="{Binding ID}" 
                                                IsReadOnly="True"/>
                            <DataGridTextColumn Header="Description"
                                                Binding="{Binding Desc}"
                                                IsReadOnly="True"/>
                            <DataGridTemplateColumn Header="Progress">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <ProgressBar Value="{Binding Value}" />
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>
    </Grid>
</Window>

  這裡用到了我自己的一個類庫:GeneralTool.General,可以通過Nuget下載,

支援將介面上的控制元件繫結到ViewModel中,同時也支援將View層的介面事件也可以繫結過去,

當然,還有一些其它的特性,這裡不多說

ViewModel層程式碼

using System;
using System.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using GeneralTool.General.WPFHelper;

namespace MainViews
{
    public class MasterVIewModel : BaseNotifyModel
    {
        private DataTable table = new DataTable();
        /// <summary>
        /// 主表
        /// </summary>
        public DataTable Table
        {
            get => this.table;
            set => this.RegisterProperty(ref this.table, value);
        }

        /// <summary>
        /// 展開
        /// </summary>
        public ICommand RowDetailCommand { get; set; }

        /// <summary>
        /// 隨機更新Progress
        /// </summary>
        public ICommand RandomCommand { get; set; }

        /// <summary>
        /// 繫結介面上的主DataGrid(當然你也可以通過View在繫結DataContext時傳遞進來)
        /// </summary>
        public DataGrid ViewGrid { get; set; }

        public MasterVIewModel()
        {
            this.RowDetailCommand = new SimpleCommand<DataRowView>(RowDetailsMethod);
            this.RandomCommand = new SimpleCommand<DataRowView>(RandomMethod);
            InitTable();
        }

        /// <summary>
        /// 初始化主表
        /// </summary>
        private void InitTable()
        {
            this.Table.Columns.Add("Icon");
            this.Table.Columns.Add("ID");
            this.Table.Columns.Add("Value");
            this.Table.Columns.Add("Progress");
            this.Table.Columns.Add("SubTable", typeof(DataTable));

            this.Table.Rows.Add("+", 1, 50, 50, DBNull.Value);
            this.Table.Rows.Add("+", 2, 70, 70, DBNull.Value);
        }

        /// <summary>
        /// 隨機更新子表的進度值
        /// </summary>
        /// <param name="arg"></param>
        private void RandomMethod(DataRowView arg)
        {
            if (arg == null) return;
            //隨機更新當前行的Progress
            var dt = arg.Row["SubTable"] as DataTable;
            if (dt == null)
                return;

            //將當前行子表的進度條值隨機更新一個數據
            dt.Rows[0]["Value"] = new Random().Next(0, 101);
        }

        /// <summary>
        /// 點選主表的+ - 號時的處理方法
        /// </summary>
        /// <param name="rowView"></param>
        private void RowDetailsMethod(DataRowView rowView)
        {
            var row = rowView.Row;
            var content = row["Icon"] + "";
            if (content == "+")
            {
                //顯示出來
                row["SubTable"] = this.GetSubTable(row["ID"]);
                this.ViewGrid.SetDetailsVisibilityForItem(rowView, Visibility.Visible);
                row["Icon"] = "-";
            }
            else
            {
                //隱藏
                this.ViewGrid.SetDetailsVisibilityForItem(rowView, Visibility.Collapsed);
                row["Icon"] = "+";
                row["SubTable"] = null;
            }
        }

        /// <summary>
        /// 獲取一個子Table
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private DataTable GetSubTable(object id)
        {
            var table = new DataTable();
            table.Columns.Add("ID");
            table.Columns.Add("Desc");
            table.Columns.Add("Value");
            table.Rows.Add(id, Guid.NewGuid(), 80);
            return table;
        }
    }
}

  效果圖