wpf需求及实现方法 动态创建控件 对数据模板任意对象操作 查找由 DataTemplate 生成的元素 查找由 ControlTemplate 生成的元素

46 篇文章 1 订阅

 我想实现一个支持多设备同时更新固件的应用。如下图

 

插入多少个设备就显示多少个进度度。每个进度条上显示对应的串口及进度。

最终实现演示如下:

          public MainWindow()
        {
            InitializeComponent();

            List<DownloadProgress> test = new List<DownloadProgress>();
            test.Add(new DownloadProgress() { Name = "COM1", Color = "#bf00ee" });
            test.Add(new DownloadProgress() { Name = "COM2", Color = "#1122ee" });
            test.Add(new DownloadProgress() { Name = "COM3", Color = "#005566" });
            test.Add(new DownloadProgress() { Name = "COM4", Color = "#778899" });
            test.Add(new DownloadProgress() { Name = "COM5", Color = "#bf00ee" });
            test.Add(new DownloadProgress() { Name = "COM6", Color = "#1122ee" });
            test.Add(new DownloadProgress() { Name = "COM7", Color = "#005566" });
            test.Add(new DownloadProgress() { Name = "COM8", Color = "#778899" });
            myListBox.ItemsSource = test;
        }


private void Button_Click_1(object sender, RoutedEventArgs e)
        {

            for (int i = 0; i < myListBox.Items.Count; i++)
            {
                //    Object o = myListBox.Items.GetItemAt(i);
                ListBoxItem myListBoxItem = (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.GetItemAt(i)));
                // Getting the currently selected ListBoxItem
                // Note that the ListBox must have
                // IsSynchronizedWithCurrentItem set to True for this to work
                // ListBoxItem myListBoxItem = (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem));

                // Getting the ContentPresenter of myListBoxItem
                ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);

                // Finding textBlock from the DataTemplate that is set on that ContentPresenter
                DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
                //TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName("textBlock", myContentPresenter);

                // Do something to the DataTemplate-generated TextBlock
                //MessageBox.Show("The text of the TextBlock of the selected list item: "  + myTextBlock.Text);
                ProgressBar myProgress = (ProgressBar)myDataTemplate.FindName("Progress", myContentPresenter);
                myProgress.Value = i+10;

            }
}

界面

<Window x:Class="WpfM20UpdateFW.MainWindow"
        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:local="clr-namespace:WpfM20UpdateFW"
        mc:Ignorable="d"
        Title="M20 Update Firmware V1.0   " Height="600" Width="800" Closed="Window_Closed">

    <Window.Resources>
        <RoutedUICommand x:Key="download" Text="download"/>
    </Window.Resources>
    <Window.InputBindings>
        <KeyBinding Gesture="Alt+D" Key="D"  Command="{StaticResource download}"></KeyBinding>
    </Window.InputBindings>
    <Window.CommandBindings>
        <CommandBinding Command="{StaticResource download}" CanExecute="Button_Click"></CommandBinding>
    </Window.CommandBindings>
    <Grid>
        <Grid ShowGridLines="false" MinWidth="20" FocusManager.FocusedElement="{Binding ElementName=download}">
            <Grid.RowDefinitions>
                <RowDefinition  Height="0.05*"></RowDefinition>
                <RowDefinition  Height="0.55*"></RowDefinition>
                <RowDefinition  Height="0.3*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.6*"></ColumnDefinition>
                <ColumnDefinition Width="0.2*"></ColumnDefinition>
                <ColumnDefinition Width="0.2*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <TextBox x:Name="Path" Grid.Row="0" Grid.Column="0" IsReadOnly="True"/>
            <Button Grid.Row="0" Grid.Column="1" Click="Button_Click_1">Open...</Button>
            <Button x:Name="download" Grid.Row="0" Grid.Column="2" Click="Button_Click" >Download</Button>
            <ListBox  Grid.Row="1"  Grid.ColumnSpan="3" x:Name="myListBox" HorizontalContentAlignment="Stretch">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <ProgressBar x:Name="Progress"/>
                            <TextBlock x:Name="textBlock" FontSize="22" HorizontalAlignment="Center" VerticalAlignment="Center">
                                <TextBlock.Text >
                                    <MultiBinding StringFormat="{}{0}   {1}%">
                                        <Binding Path="Name"/>
                                        <Binding Path="Value" ElementName="Progress"/>
                                    </MultiBinding>
                                </TextBlock.Text>
                            </TextBlock>
                            
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

            <TextBox x:Name="logText"  Grid.Row="2" Grid.ColumnSpan="3" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" AcceptsReturn="True" IsReadOnly="True" />
        </Grid>
    </Grid>
</Window>

现在已经实现了动态显示多个进度条。还需要实现:

1.进度前显示串口号,比如COM1等。

2.每个进度条能控制显示进度。

 

<Window x:Class="WpfM20UpdateFW.MainWindow"
        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:local="clr-namespace:WpfM20UpdateFW"
        mc:Ignorable="d"
        Title="M20 Update Firmware V1.0   " Height="600" Width="800" Closed="Window_Closed">

    <Window.Resources>
        <RoutedUICommand x:Key="download" Text="download"/>
    </Window.Resources>
    <Window.InputBindings>
        <KeyBinding Gesture="Alt+D" Key="D"  Command="{StaticResource download}"></KeyBinding>
    </Window.InputBindings>
    <Window.CommandBindings>
        <CommandBinding Command="{StaticResource download}" CanExecute="Button_Click"></CommandBinding>
    </Window.CommandBindings>
    <Grid>
        <Grid ShowGridLines="false" MinWidth="20" FocusManager.FocusedElement="{Binding ElementName=download}">
            <Grid.RowDefinitions>
                <RowDefinition  Height="0.05*"></RowDefinition>
                <RowDefinition  Height="0.55*"></RowDefinition>
                <RowDefinition  Height="0.3*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0.6*"></ColumnDefinition>
                <ColumnDefinition Width="0.2*"></ColumnDefinition>
                <ColumnDefinition Width="0.2*"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <TextBox x:Name="Path" Grid.Row="0" Grid.Column="0" IsReadOnly="True"/>
            <Button Grid.Row="0" Grid.Column="1" Click="Button_Click_1">Open...</Button>
            <Button x:Name="download" Grid.Row="0" Grid.Column="2" Click="Button_Click" >Download</Button>
            <ListBox  Grid.Row="1"  Grid.ColumnSpan="3" x:Name="list" HorizontalContentAlignment="Stretch">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <ProgressBar x:Name="Progress"/>
                            <Label Content="{Binding Path=Value,ElementName=Progress}" ContentStringFormat=" {0}%" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="22"/>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

            <TextBox x:Name="logText"  Grid.Row="2" Grid.ColumnSpan="3" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" AcceptsReturn="True" IsReadOnly="True" />
        </Grid>
    </Grid>
</Window>

如何解决1:使用MultiBinding 解决了。

 <Label Content="{Binding Path=Value,ElementName=Progress}" ContentStringFormat="{} {0}%" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="22"/>

 

以下贴出MSDN官方的解决方法

ControlTemplate

https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/controls/how-to-find-controltemplate-generated-elements

DataTemplate

https://docs.microsoft.com/zh-cn/dotnet/framework/wpf/data/how-to-find-datatemplate-generated-elements

以上要注意常出现null的问题

ControlTemplate里这种用法只能获取直接关联的子元素,如果是像ItemBox,ItemView等等里的item元素是获取不到的,还有,因为UI需要加载窗体,需要一个时间,所以要注意顺序,不能在构造函数中获取ControlTemplate,那样会显示null,可以再窗体load事件以及控件的事件中使用

DataTemplate要注意以上方法是通过遍历item得到的,也就是说如果你的ItemBox,ItemView等等还没加载数据源,即没有item时不能使用,会报null

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黄人软件

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值