WPF学习笔记-数据采集与监控项目03-课程总览(ItemsControl控件)
阅读原文时间:2023年07月09日阅读:1

以下是学习笔记:

https://www.bilibili.com/video/BV1gq4y1D76d?p=57&spm_id_from=pageDriver&vd_source=3f21d2e208ef0bf2c49a9be7560735e5

重点内容:学习课程总览的数据绑定

1,滚动页面效果:

把页面放入ScrollViewer中

2,课程总览的页面

        <!--课程总览,第3行-->  
        <Grid Margin="10,0" Grid.Row="2">  
            <Grid.RowDefinitions>  
                <RowDefinition Height="40"/>  
                <RowDefinition/>  
            </Grid.RowDefinitions>  
            <!--第一行的标题-->  
            <TextBlock Text="课程总览" Foreground="#3f4c5d" VerticalAlignment="Center" FontSize="15"  
                   FontWeight="Bold"/>  
            <TextBlock HorizontalAlignment="right" VerticalAlignment="Center">  
            <Hyperlink FontSize="15">详情</Hyperlink>  
            </TextBlock>  
            <!--第二行的课程展示,这个最重要-->  
            <ItemsControl ItemsSource="{Binding CourseSeriesList}" Grid.Row="1">  
                <!--需要修改容器模板-->  
                <ItemsControl.ItemsPanel>  
                    <ItemsPanelTemplate>  
                        <VirtualizingStackPanel/>  
                    </ItemsPanelTemplate>  
                </ItemsControl.ItemsPanel>  
                <ItemsControl.ItemTemplate>  
                    <DataTemplate>  
                        <Border Background="White" CornerRadius="10">  
                            <Border.Effect>  
                                <DropShadowEffect Color="Gray" ShadowDepth="0" BlurRadius="10" Opacity="0.2" Direction="0"></DropShadowEffect>  
                            </Border.Effect>  
                            <Grid Height="70">  
                                <!--分成三列-->  
                                <Grid.ColumnDefinitions>  
                                    <ColumnDefinition/>  
                                    <ColumnDefinition/>  
                                    <ColumnDefinition Width="3.5\*"/>  
                                </Grid.ColumnDefinitions>

                                <!--三列之间的分割竖线-->  
                                <Border BorderBrush="#ddd" BorderThickness="0,0,1,0" Margin="0,10"/>  
                                <Border BorderBrush="#ddd" BorderThickness="0,0,1,0" Margin="0,10" Grid.Column="1"/>

                                <!--第一列-->  
                                <TextBlock Text="{Binding CourseName}" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#444"/>

                                <!--第二列-->  
                                <lvc:PieChart Grid.Column="1" LegendLocation="Right" InnerRadius="10" Margin="0,0,10,0" Series="{Binding SeriesCollection}">  
                                    <!--<lvc:PieChart.Series>-->  
                                    <!--<lvcs:SeriesCollection>  
                                        <lvc:PieSeries Title="111" Values="12" DataLabels="False"/>  
                                        <lvc:PieSeries Title="111" Values="12" DataLabels="False"/>  
                                        <lvc:PieSeries Title="111" Values="12" DataLabels="False"/>  
                                        <lvc:PieSeries Title="111" Values="12" DataLabels="False"/>  
                                        <lvc:PieSeries Title="111" Values="12" DataLabels="False"/>  
                                    </lvcs:SeriesCollection>  
                                </lvc:PieChart.Series>-->  
                                    <lvc:PieChart.ChartLegend>  
                                        <lvc:DefaultLegend BulletSize="10"/>  
                                    </lvc:PieChart.ChartLegend>  
                                    <lvc:PieChart.DataTooltip>  
                                        <lvc:DefaultLegend BulletSize="10"/>  
                                    </lvc:PieChart.DataTooltip>  
                                </lvc:PieChart>

                                <!--第三列-->  
                                <ItemsControl Grid.Column="2" ItemsSource="{Binding SeriesLsit}">  
                                    <!--修改控件模板-->  
                                    <ItemsControl.ItemsPanel>  
                                        <ItemsPanelTemplate>  
                                            <!--设置列数,超过5列自动换行-->  
                                            <!--<UniformGrid Columns="5"/>-->  
                                            <!--设置动态的列数-->  
                                            <UniformGrid Columns="{Binding DataContext.ItemCount,RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor}}"/>  
                                        </ItemsPanelTemplate>  
                                    </ItemsControl.ItemsPanel>  
                                    <ItemsControl.ItemTemplate>  
                                        <DataTemplate>  
                                            <Grid VerticalAlignment="Center" HorizontalAlignment="Center">  
                                                <Grid.ColumnDefinitions>  
                                                    <ColumnDefinition/>  
                                                    <ColumnDefinition/>  
                                                </Grid.ColumnDefinitions>  
                                                <Grid.RowDefinitions>  
                                                    <RowDefinition MinHeight="24"/>  
                                                    <RowDefinition MinHeight="24"/>  
                                                </Grid.RowDefinitions>  
                                                <TextBlock Text="{Binding SeriesName}" VerticalAlignment="Center"/>  
                                                <TextBlock Text="{Binding CurrentValue}" Grid.Row="1" VerticalAlignment="Center"/>  
                                                <TextBlock Text="{Binding IsGrowing ,Converter={StaticResource BoolToArrowConverter\_suibian}}"  
                                                       Foreground="{Binding IsGrowing,Converter={StaticResource BoolToBrushConverter\_suibian}}" Grid.Column="1" VerticalAlignment="Center" Margin="10,0,0,0"/>  
                                                <TextBlock Text="{Binding ChangeRate}" Grid.Column="1"  
                                                       Foreground="{Binding IsGrowing,Converter={StaticResource BoolToBrushConverter\_suibian}}" Grid.Row="1" VerticalAlignment="Center" Margin="10,0,0,0"/>  
                                            </Grid>  
                                        </DataTemplate>  
                                    </ItemsControl.ItemTemplate>  
                                </ItemsControl>  
                                <!--第三列的原始草稿模板-->  
                                <!--<UniformGrid Columns="5" Grid.Column="2">  
                                <Grid VerticalAlignment="Center" HorizontalAlignment="Center">  
                                    <Grid.ColumnDefinitions>  
                                        <ColumnDefinition/>  
                                        <ColumnDefinition/>  
                                    </Grid.ColumnDefinitions>  
                                    <Grid.RowDefinitions>  
                                        <RowDefinition/>  
                                        <RowDefinition/>  
                                    </Grid.RowDefinitions>  
                                    <TextBlock Text="云课堂"/>  
                                    <TextBlock Text="161" Grid.Row="1"/>  
                                    <TextBlock Text="|" Grid.Column="1"/>  
                                    <TextBlock Text="75%" Grid.Column="1" Grid.Row="1"/>  
                                </Grid>  
                            </UniformGrid>-->

                            </Grid>  
                        </Border>  
                    </DataTemplate>  
                </ItemsControl.ItemTemplate>  
            </ItemsControl>

3,Model

/// <summary>  
/// 课程类  
/// </summary>  

public class CourseServiceModel
{
public string CourseName { get; set; }
public SeriesCollection SeriesCollection { get; set; }
public ObservableCollection SeriesLsit { get; set; }
}

4,ViewModel

public class FirstPageViewModel:NotifyBase
{
private int _instrumentValue=0;

    public int InstrumentValue  
    {  
        get { return \_instrumentValue; }  
        set { \_instrumentValue = value; this.DoNotify(); }  
    }

    private int \_itemCount;  
    //设置一个变量,给一个动态数量排列  
    public int ItemCount  
    {  
        get { return \_itemCount; }  
        set { \_itemCount = value; this.DoNotify(); }  
    }

    /// <summary>  
    /// 课程集合  
    /// </summary>  
    public ObservableCollection<CourseServiceModel> CourseSeriesList { get; set; }=new ObservableCollection<CourseServiceModel>();

    Random random=new Random();

    /// <summary>  
    /// 线程的开关  
    /// </summary>  
    private bool taskSwitch=true;

    /// <summary>  
    /// 开启的线程集合  
    /// </summary>  
    List<Task> tasklList=new List<Task>();

    public FirstPageViewModel()  
    {  
        this.RefreshInstrumentValue();  
        this.InitCourseSeries();  
    }

    void InitCourseSeries()  
    {  
        #region 测试添加数据

        //CourseSeriesList.Add(new CourseServiceModel()  
        //{

        //    CourseName = "Java从入门到放弃",  
        //    SeriesCollection = new SeriesCollection()  
        //    {  
        //        new PieSeries()  
        //        {  
        //            Title = "1111",  
        //            Values = new ChartValues<ObservableValue> {(new ObservableValue(10))},  
        //            DataLabels = false,  
        //        },  
        //        new PieSeries()  
        //        {  
        //            Title = "2222",  
        //            Values = new ChartValues<ObservableValue> {(new ObservableValue(20))},  
        //            DataLabels = false,  
        //        },  
        //        new PieSeries()  
        //        {  
        //            Title = "3333",  
        //            Values = new ChartValues<ObservableValue> {(new ObservableValue(30))},  
        //            DataLabels = false,  
        //        },  
        //        new PieSeries()  
        //        {  
        //            Title = "4444",  
        //            Values = new ChartValues<ObservableValue> {(new ObservableValue(40))},  
        //            DataLabels = false,  
        //        },  
        //    },  
        //    SeriesLsit = new ObservableCollection<SeriesModel>()  
        //    {  
        //        new SeriesModel(){SeriesName = "云课堂1",CurrentValue = 161,IsGrowing = false,ChangeRate = 75},  
        //        new SeriesModel(){SeriesName = "云课堂2",CurrentValue = 161,IsGrowing = true,ChangeRate = 50},  
        //        new SeriesModel(){SeriesName = "云课堂3",CurrentValue = 161,IsGrowing = false,ChangeRate = 90},  
        //        new SeriesModel(){SeriesName = "云课堂4",CurrentValue = 161,IsGrowing = true,ChangeRate = 85},  
        //        new SeriesModel(){SeriesName = "云课堂5",CurrentValue = 161,IsGrowing = false,ChangeRate = 78},  
        //    }  
        //});  
        //CourseSeriesList.Add(new CourseServiceModel()  
        //{  
        //    CourseName = "Java从入门到放弃",  
        //    SeriesCollection = new SeriesCollection()  
        //    {  
        //        new PieSeries()  
        //        {  
        //            Title = "1111",  
        //            Values = new ChartValues<ObservableValue> {(new ObservableValue(10))},  
        //            DataLabels = false,  
        //        },  
        //        new PieSeries()  
        //        {  
        //            Title = "2222",  
        //            Values = new ChartValues<ObservableValue> {(new ObservableValue(20))},  
        //            DataLabels = false,  
        //        },  
        //        new PieSeries()  
        //        {  
        //            Title = "3333",  
        //            Values = new ChartValues<ObservableValue> {(new ObservableValue(30))},  
        //            DataLabels = false,  
        //        },  
        //        new PieSeries()  
        //        {  
        //            Title = "4444",  
        //            Values = new ChartValues<ObservableValue> {(new ObservableValue(40))},  
        //            DataLabels = false,  
        //        },  
        //    },  
        //    SeriesLsit = new ObservableCollection<SeriesModel>()  
        //    {  
        //        new SeriesModel(){SeriesName = "云课堂1",CurrentValue = 161,IsGrowing = false,ChangeRate = 75},  
        //        new SeriesModel(){SeriesName = "云课堂2",CurrentValue = 161,IsGrowing = true,ChangeRate = 50},  
        //        new SeriesModel(){SeriesName = "云课堂3",CurrentValue = 161,IsGrowing = false,ChangeRate = 90},  
        //        new SeriesModel(){SeriesName = "云课堂4",CurrentValue = 161,IsGrowing = true,ChangeRate = 85},  
        //        new SeriesModel(){SeriesName = "云课堂5",CurrentValue = 161,IsGrowing = false,ChangeRate = 78},  
        //        new SeriesModel(){SeriesName = "其他",CurrentValue = 161,IsGrowing = false,ChangeRate = 78},  
        //    }  
        //});

        #endregion

        var cList = LocalDataAccess.GetInstance().GetCoursePlayRecord();  
        //获取最大的数量  
        this.ItemCount = cList.Max(c => c.SeriesLsit.Count);

        //【特别注意】用这个方式,相当于把之前的对象替换掉了,页面接收不到数据的  
        //this.CourseSeriesList = new ObservableCollection<CourseServiceModel>(cList);

        //要使用CourseSeriesList.Add(item)方式,页面才能接收到数据  
        foreach (var item in cList)  
        {  
            this.CourseSeriesList.Add(item);  
        }  
    }

    void RefreshInstrumentValue()  
    {  
        var task = Task.Factory.StartNew(new Action(async () =>  
        {  
            while (taskSwitch)  
            {  
                //0和100是最大值和最小值,这里为了演示效果是写死的,后期可用变量替代。  
                InstrumentValue = random.Next(Math.Max(this.InstrumentValue - 5,0), Math.Min( this.InstrumentValue + 5,100));

                //停顿1秒刷新  
                await Task.Delay(1000);  
            }  
        }));  
        tasklList.Add(task);  
    }

    public void Dispose()  
    {  
        try  
        {  
            taskSwitch = false;

            //等待所有线程结束  
            Task.WaitAll(this.tasklList.ToArray());  
        }  
        catch (Exception e)  
        {  
        }  
    }

}

5,数据的查询

    public List<CourseServiceModel> GetCoursePlayRecord()  
    {  
        try  
        {  
            List<CourseServiceModel> cModelList = new List<CourseServiceModel>();  
            if (DBConnection())  
            {  
                string userSql = @"select a.course\_name,a.course\_id ,b.play\_count,b.is\_growing,b.growing\_rate  
                , c.platforms\_name  
                from courses a  
            left join play\_record b  
            on a.course\_id = b.course\_id  
            left join platforms c  
            on b.platform\_id = c.platforms\_id  
            order by a.course\_id,c.platforms\_id";

                adapter = new SqlDataAdapter(userSql, conn);  
                DataTable table = new DataTable();  
                int count = adapter.Fill(table);

                string courseId = "";  
                CourseServiceModel cModel = null;  
                foreach (DataRow dr in table.AsEnumerable())  
                {  
                    string tempId = dr.Field<string>("course\_id");  
                    if (courseId != tempId)  
                    {  
                        courseId = tempId;  
                        cModel = new CourseServiceModel();  
                        cModelList.Add(cModel);

                        cModel.CourseName = dr.Field<string>("course\_name");  
                        cModel.SeriesCollection = new LiveCharts.SeriesCollection();  
                        cModel.SeriesLsit = new ObservableCollection<SeriesModel>();  
                    }

                    if (cModel != null)  
                    {  
                        cModel.SeriesCollection.Add(new PieSeries()  
                        {  
                            Title = dr.Field<string>("platforms\_name"),  
                            Values = new ChartValues<ObservableValue>  
                                {(new ObservableValue(dr.Field<int>("play\_count")))},  
                            DataLabels = false  
                        });  
                    }

                    cModel.SeriesLsit.Add(new SeriesModel()  
                    {  
                        SeriesName = dr.Field<string>("platforms\_name"),  
                        CurrentValue = dr.Field<int>("play\_count"),  
                        IsGrowing = dr.Field<int>("is\_growing") == 1,  
                        ChangeRate = dr.Field<int>("growing\_rate"),  
                    });  
                }

            }

            return cModelList;  
        }  
        catch (Exception e)  
        {  
            throw e;  
        }  
        finally  
        {  
            this.Dispose();  
        }

    }

单选框效果

1,控件模板

<UserControl.Resources>  
    <ControlTemplate TargetType="RadioButton" x:Key="CategoryItemButtonTemplate">  
        <!--定义视觉树-->  
        <Grid Background="Transparent" Margin="10,0">  
            <Border Background="#eee" CornerRadius="5" Name="back">  
                <TextBlock Text="{TemplateBinding Content}" Margin="15,6" VerticalAlignment="Center" HorizontalAlignment="Center"/>  
            </Border>  
        </Grid>  
        <!--定义视觉树\_End-->  
        <!--定义触发器-->  
        <ControlTemplate.Triggers>  
            <Trigger Property="IsChecked" Value="True">  
                <Setter Property="Background" Value="Orange" TargetName="back"/>  
                <Setter Property="Foreground" Value="white"/>  
            </Trigger>  
        </ControlTemplate.Triggers>  
        <!--定义触发器\_End-->  
    </ControlTemplate>  
</UserControl.Resources>

2,

                <StackPanel Orientation="Horizontal" VerticalAlignment="Center">  
                    <TextBlock  Text="课程分类" VerticalAlignment="Center" />  
                    <!--ItemsSource用来数据绑定-->  
                    <ItemsControl ItemsSource="{Binding CategoryCourses}">  
                        <!--布局进行控制的面板-->  
                        <ItemsControl.ItemsPanel>  
                            <!--控件的容器外观-->  
                            <ItemsPanelTemplate>  
                                <StackPanel Orientation="Horizontal"/>  
                            </ItemsPanelTemplate>  
                        </ItemsControl.ItemsPanel>  
                        <ItemsControl.ItemTemplate>  
                            <!--数据模板-->  
                            <DataTemplate>  
                                <!--使用分组GroupName="course"使每一行相互隔离-->  
                                <RadioButton Content="{Binding CategoryName}" IsChecked="{Binding IsSelected}"  
                                             Template="{StaticResource CategoryItemButtonTemplate}" GroupName="course"/>  
                            </DataTemplate>  
                        </ItemsControl.ItemTemplate>  
                    </ItemsControl>  
                </StackPanel>

                <StackPanel Orientation="Horizontal" Grid.Row="1" VerticalAlignment="Center">  
                    <TextBlock   Text="技术分类" VerticalAlignment="Center" />  
                    <ItemsControl ItemsSource="{Binding CategoryTechnology}">  
                        <ItemsControl.ItemsPanel>  
                            <ItemsPanelTemplate>  
                                <StackPanel Orientation="Horizontal"/>  
                            </ItemsPanelTemplate>  
                        </ItemsControl.ItemsPanel>  
                        <ItemsControl.ItemTemplate>  
                            <DataTemplate>  
                                <RadioButton Content="{Binding CategoryName}" IsChecked="{Binding IsSelected}"  
                                             Template="{StaticResource CategoryItemButtonTemplate}" GroupName="technology"/>  
                            </DataTemplate>  
                        </ItemsControl.ItemTemplate>  
                    </ItemsControl>  
                </StackPanel>

                <StackPanel Orientation="Horizontal" Grid.Row="2" VerticalAlignment="Center">  
                    <TextBlock Text="授课老师" VerticalAlignment="Center" />  
                    <ItemsControl ItemsSource="{Binding CategoryTeacher}">  
                        <ItemsControl.ItemsPanel>  
                            <ItemsPanelTemplate>  
                                <StackPanel Orientation="Horizontal"/>  
                            </ItemsPanelTemplate>  
                        </ItemsControl.ItemsPanel>  
                        <ItemsControl.ItemTemplate>  
                            <DataTemplate>  
                                <RadioButton Content="{Binding CategoryName}" IsChecked="{Binding IsSelected}"  
                                             Template="{StaticResource CategoryItemButtonTemplate}" GroupName="teacher"/>  
                            </DataTemplate>  
                        </ItemsControl.ItemTemplate>  
                    </ItemsControl>  
                </StackPanel>

3,

public class CoursePageViewModel  
{  
    public ObservableCollection<CategoryItemModel> CategoryCourses { get; set; }  
    public ObservableCollection<CategoryItemModel> CategoryTechnology { get; set; }  
    public ObservableCollection<CategoryItemModel> CategoryTeacher { get; set; }

    public CoursePageViewModel()  
    {  
        this.CategoryCourses = new ObservableCollection<CategoryItemModel>();  
        this.CategoryCourses.Add(new CategoryItemModel("全部", true));  
        this.CategoryCourses.Add(new CategoryItemModel("公开课"));  
        this.CategoryCourses.Add(new CategoryItemModel("VIP课程"));

        this.CategoryTechnology = new ObservableCollection<CategoryItemModel>();  
        this.CategoryTechnology.Add(new CategoryItemModel("全部", true));  
        this.CategoryTechnology.Add(new CategoryItemModel("C#"));  
        this.CategoryTechnology.Add(new CategoryItemModel("Python"));

        this.CategoryTeacher = new ObservableCollection<CategoryItemModel>();  
        this.CategoryTeacher.Add(new CategoryItemModel("全部", true));  
        this.CategoryTeacher.Add(new CategoryItemModel("Jason"));  
        this.CategoryTeacher.Add(new CategoryItemModel("Mason"));  
    }  
}