问题 动态创建TextBlocks和网格

玻璃灯

众所周知的成员
加入
2019年11月22日
消息
126
编程经验
Beginner
这看起来很毫无意义,但我想知道这是可能的,练习做到这一点。

我要键入文本框,并将文本镜像到表单上,如图所示。即使是我刚才描述的完全正确,我不想将TextBlock绑定到字符串属性。我希望将镜像到表单上的单词,包括每个字母的单个网格列中的单个TextBlock,这将进入主网格上的单元格,可能以文本框下方的形式为中心。

所以,如果我键入这个词"Hello"进入文本框中将创建五个列网格,在每列中将是福彩12选5走势图文本块,显示单词的单个字母"Hello"。我很难考虑尝试这一点,因为我不知道如何在没有明确创建和命名控件的情况下可以完成。我想用福彩12选5走势图"foreach(char c在stringname中)"循环,每次列出列时,都会制作福彩12选5走势图文本块,添加到网格中并更改为相应的字母,但也许我正在考虑错误?我该怎么办?

谢谢
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
TextBlocks等片段元素不包括TextBox控件的功能。因此,因为功能有点不同,所以Fragment元素TextBlocks没有帖子换个事件处理程序,但是文本框控件存在。 如何:检测文本框中的文本已更改 - WPF

检测何时输入"H",您将建立输入的键的变量,并将变量扩展为键入新密钥。另外检查键按压诸如空间栏和返回和返回键,以从键入时从变量中删除字母/字符。

对于每个新的char,您将分别使用grid.columndefinition和grid.rowdefinition构成网格。正如您之前的主题所做的那样: 问题 - 包装板可以互相对齐吗? 并将控件添加到网格的新部分。
 
Last edited:

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,892
地点
切萨皮克,va.
编程经验
10+
我知道你想使用网格,但这是我使用水平堆叠面板的快速和肮脏的实现:
screenshot_4.png.


代码很简单。没有明确命名的控件。所有使用WPF MVVM的良品。
MainWindow.xaml:
<Window x:Class="WpfBanner.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:WpfBanner"
        mc:Ignorable="d"
        Title="WPF Banner" Height="450" Width="800">
    <StackPanel>
        <TextBox Text="{Binding Path=Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
        <ItemsControl ItemsSource="{Binding Chars}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"
                                HorizontalAlignment="Center"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="1"
                            BorderBrush="Black"
                            Width="50">
                        <TextBlock Text="{Binding}"
                                   FontSize="20"
                                   Margin="10"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Bottom"/>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>    </StackPanel>
</Window>
MainWindow.xaml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfBanner
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            var banner = new Banner() { Text = "Hello, World" };
            DataContext = new BannerViewModel(banner);
            InitializeComponent();
        }
    }
}
BannerViewModel.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace WpfBanner
{
    class BannerViewModel : INotifyPropertyChanged
    {
        readonly Banner _banner;

        public string Text
        {
            get => _banner.Text;

            set
            {
                _banner.Text = value;
                NotifyPropertyChanged();
                NotifyPropertyChanged("Chars");
            }
        }

        public List<string> Chars => Text.Select(c => c.ToString()).ToList();

        public BannerViewModel(Banner banner)
            => _banner = banner;

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged([CallerMemberName] string info = "")
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
    }
}
Banner.cs:
using System;
using System.Collections.Generic;
using System.Text;

namespace WpfBanner
{
    class Banner
    {
        public string Text { get; set; }
    }
}
 

玻璃灯

众所周知的成员
加入
2019年11月22日
消息
126
编程经验
Beginner
跳伞运动员是福彩12选5走势图很好的非常有用的例子,谢谢你写作。福彩12选5走势图StackPanel绝对没问题。现在我必须咬住子弹并了解这个项目控制和数据库的东西。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,892
地点
切萨皮克,va.
编程经验
10+
所有魔法都在视图模型中。视图模型呈现文本和字符串列表,其中每个字符串是文本的字母。每次TextBox会告诉视图模型更新文本时,视图模型会更新文本和字符串列表。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,892
地点
切萨皮克,va.
编程经验
10+
将项目视为列表框的基类。 ListBox只是福彩12选5走势图垂直的StackPanel,它将其项目作为TextBlocks。因此,项目本eltemplate将是福彩12选5走势图垂直的stackpanel,并且数据库将是TextBlock。
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
我只是很高兴的跳伞运动员接受了我的建议,避免了福彩12选5走势图网格。否则,我们可能会像你的最后一次挂机一样,我们可能有另福彩12选5走势图主题,但知道它可以完成它,但知道它需要更多代码来写入,而不是要么想要做。我还没有把这个榜样在网格中做到这一点,但对于这个例子来说,这很好。我也喜欢你用notifypropertychanged,这是现在的大多数人现在不打扰。好跳伞运动员!
 

玻璃灯

众所周知的成员
加入
2019年11月22日
消息
126
编程经验
Beginner
我将首先去福彩12选5走势图StackPanel,但我以为我被建议使用网格而不是哈哈。

你能解释你的mainWindow.xaml中的23行吗?文字="{Binding}"没有绑定任何东西,那里发生了什么?
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,892
地点
切萨皮克,va.
编程经验
10+
On line 11, there is this code which tells the ItemsControl that the objects will be bound to the Chars property of the DataContext:
C#:
<ItemsControl ItemsSource="{Binding Chars}">

So when it's time to create each item, each object from the Chars list is passed on to an instance of the DataTemplate for binding. Since Chars is a List<string>, that means that each object passed on is just a string. (See 我的回复 to your other thread where I said you can just bind to a string.) By saying {捆绑}, I am telling WPF to bind to the entire object, is this case the string. (See 指定值的路径)
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
我将首先去福彩12选5走势图StackPanel,但我以为我被建议使用网格而不是哈哈。
哈哈!嗯,你想当时学习XAML和WPF,我认为这将是福彩12选5走势图更好的方法,让你开始,通过学习XAML后端,你可以用XMAL使用不同的控件。我也以为这个网格是你要做的事情更好的榜样,它仍然是你所做的事情的可行控制;正如我所展示了一些关于它如何用单独的网格完成的其他主题的示例,包括Youtube教程,我只是没有时间在当时写出来。这是它非常易于使用的对齐面板(堆叠面板相似),但如果您为客户工作为开发人员,他们可以坚持认为没有这样的控制在其应用中使用。

那么你怎么做在没有被允许的情况下做你需要做的事情?几乎每个开发人员都在某种程度上发现了这种情况。当您选择基本分配的基本分配来测试自己的控制时,它并不是福彩12选5走势图很好的情况,这些控制器旨在使您的生活更轻松。这里的挑战是尝试和建立依赖于对齐面板的东西,而是没有;更具挑战性,更不用说,有趣!它还教会您在未来雇主的情况下放入这种情况时适应新技能。

我最初开始为您的其他网格相关的帖子写福彩12选5走势图git,但我和跳伞者已经有时间更新它。也许有一天我们会很快重新审视它。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,892
地点
切萨皮克,va.
编程经验
10+
And here's basically the same code above, but displaying as a Grid instead of a StackPanel. Just the modified/new code below:

MainWindow.xaml:
<Window x:Class="WpfBanner.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:WpfBanner"
        mc:Ignorable="d"
        Title="WPF Banner" Height="450" Width="800">
    <StackPanel>
        <TextBox Text="{Binding Path=Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
        <ItemsControl ItemsSource="{Binding Chars}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Grid local:GridHelpers.ColumnCount="{Binding Chars.Count}"
                          local:GridHelpers.RowCount="1"
                          HorizontalAlignment="Center"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="1"
                            BorderBrush="Black"
                            Width="50">
                        <TextBlock Text="{Binding}"
                                   FontSize="20"
                                   Margin="10"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Bottom"/>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</Window>
GridHelpers.cs:
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace WpfBanner
{
    /// <summary>
    /// Adapted from: //rachel53461.wordpress.com/2011/09/17/wpf-grids-rowcolumn-count-properties/
    /// </summary>
    public static class GridHelpers
    {
        #region RowCount Property

        /// <summary>
        /// Adds the specified number of Rows to RowDefinitions.
        /// Default Height is Auto
        /// </summary>
        public static readonly DependencyProperty RowCountProperty =
            DependencyProperty.RegisterAttached(
                "RowCount", typeof(int), typeof(GridHelpers),
                new PropertyMetadata(-1, RowCountChanged));

        public static int GetRowCount(DependencyObject obj)
            => (int)obj.GetValue(RowCountProperty);

        public static void SetRowCount(DependencyObject obj, int value)
            => obj.SetValue(RowCountProperty, value);

        public static void RowCountChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (!(obj is Grid grid) || (int)e.NewValue < 0)
                return;

            grid.RowDefinitions.Clear();

            for (int i = 0; i < (int)e.NewValue; i++)
                grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });

            SetStarRows(grid);

            RegisterForLayoutUpdate(grid);
        }

        #endregion

        #region ColumnCount Property

        /// <summary>
        /// Adds the specified number of Columns to ColumnDefinitions.
        /// Default Width is Auto
        /// </summary>
        public static readonly DependencyProperty ColumnCountProperty =
            DependencyProperty.RegisterAttached(
                "ColumnCount", typeof(int), typeof(GridHelpers),
                new PropertyMetadata(-1, ColumnCountChanged));

        public static int GetColumnCount(DependencyObject obj)
            => (int)obj.GetValue(ColumnCountProperty);

        public static void SetColumnCount(DependencyObject obj, int value)
            => obj.SetValue(ColumnCountProperty, value);

        public static void ColumnCountChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (!(obj is Grid grid) || (int)e.NewValue < 0)
                return;

            grid.ColumnDefinitions.Clear();

            for (int i = 0; i < (int)e.NewValue; i++)
                grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });

            SetStarColumns(grid);

            RegisterForLayoutUpdate(grid);
        }

        #endregion

        #region StarRows Property

        /// <summary>
        /// Makes the specified Row's Height equal to Star.
        /// Can set on multiple Rows
        /// </summary>
        public static readonly DependencyProperty StarRowsProperty =
            DependencyProperty.RegisterAttached(
                "StarRows", typeof(string), typeof(GridHelpers),
                new PropertyMetadata(string.Empty, StarRowsChanged));

        public static string GetStarRows(DependencyObject obj)
            => (string)obj.GetValue(StarRowsProperty);

        public static void SetStarRows(DependencyObject obj, string value)
            => obj.SetValue(StarRowsProperty, value);

        public static void StarRowsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (!(obj is Grid grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
                return;

            SetStarRows(grid);

            RegisterForLayoutUpdate(grid);
        }

        #endregion

        #region StarColumns Property

        /// <summary>
        /// Makes the specified Column's Width equal to Star.
        /// Can set on multiple Columns
        /// </summary>
        public static readonly DependencyProperty StarColumnsProperty =
            DependencyProperty.RegisterAttached(
                "StarColumns", typeof(string), typeof(GridHelpers),
                new PropertyMetadata(string.Empty, StarColumnsChanged));

        public static string GetStarColumns(DependencyObject obj)
            => (string)obj.GetValue(StarColumnsProperty);

        public static void SetStarColumns(DependencyObject obj, string value)
            => obj.SetValue(StarColumnsProperty, value);

        public static void StarColumnsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            if (!(obj is Grid grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
                return;

            SetStarColumns(grid);

            RegisterForLayoutUpdate(grid);
        }

        #endregion

        static void SetStarColumns(Grid grid)
        {
            string[] starColumns = GetStarColumns(grid).Split(',');

            for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
            {
                if (starColumns.Contains(i.ToString()))
                    grid.ColumnDefinitions[i].Width = new GridLength(1, GridUnitType.Star);
            }
        }

        static void SetStarRows(Grid grid)
        {
            string[] starRows = GetStarRows(grid).Split(',');

            for (int i = 0; i < grid.RowDefinitions.Count; i++)
            {
                if (starRows.Contains(i.ToString()))
                    grid.RowDefinitions[i].Height = new GridLength(1, GridUnitType.Star);
            }
        }

        static HashSet<Grid> _registered = new HashSet<Grid>();

        static void RegisterForLayoutUpdate(Grid grid)
        {
            if (_registered.Contains(grid))
                return;

            _registered.Add(grid);

            grid.LayoutUpdated += (o, e) =>
            {
                int columnCount = grid.ColumnDefinitions.Count;
                int count = 0;
                foreach (var presenter in grid.Children.OfType<ContentPresenter>())
                {
                    Grid.SetColumn(presenter, count % columnCount);
                    Grid.SetRow(presenter, count / columnCount);
                    count++;
                }
            };
        }
    }
}

基本上我服了 Rachel Lim的Gridhelper.cs 并且调整它还设置了Colin Eberhardt中概述的子元素的网格位置 how to make the Grid play nicely with the ItemsControl. In my implementation above, I'm not using a Phantom panel. I'm assuming that each DataTemplate is truly mean to live in its own grid cell. The distribution of the children among the grid cells is dependent on the ColumnCount.
 
Last edited:

玻璃灯

众所周知的成员
加入
2019年11月22日
消息
126
编程经验
Beginner
哈哈!嗯,你想当时学习XAML和WPF,我认为这将是福彩12选5走势图更好的方法,让你开始,通过学习XAML后端,你可以用XMAL使用不同的控件。我也以为这个网格是你要做的事情更好的榜样,它仍然是你所做的事情的可行控制;正如我所展示了一些关于它如何用单独的网格完成的其他主题的示例,包括Youtube教程,我只是没有时间在当时写出来。这是它非常易于使用的对齐面板(堆叠面板相似),但如果您为客户工作为开发人员,他们可以坚持认为没有这样的控制在其应用中使用。

那么你怎么做在没有被允许的情况下做你需要做的事情?几乎每个开发人员都在某种程度上发现了这种情况。当您选择基本分配的基本分配来测试自己的控制时,它并不是福彩12选5走势图很好的情况,这些控制器旨在使您的生活更轻松。这里的挑战是尝试和建立依赖于对齐面板的东西,而是没有;更具挑战性,更不用说,有趣!它还教会您在未来雇主的情况下放入这种情况时适应新技能。

我最初开始为您的其他网格相关的帖子写福彩12选5走势图git,但我和跳伞者已经有时间更新它。也许有一天我们会很快重新审视它。

不用担心,拿到你需要的一直,有很多其他主题让我撕掉我的头发 :) 也许在此阶段甚至有点在这个阶段为我提供了一点。

跳伞运动员,你的榜样与网格更加复杂,我想我会坚持仔细考虑第福彩12选5走势图。我非常欣赏你进入它的时间,但是那里有太多的我不明白。有一天,我会回来的,我毫无疑问在那里有很多有价值的编程知识,我只是无法认识到。

编辑:还有一件事,我一直在尝试谷歌了解有关使用绑定的更多信息,没有指定属性绑定,因为我不知道它究竟是什么绑定它被称为我未能找到任何内容来自谷歌。我试图搜索"="{Binding}""但即使内部引用谷歌也只是搜索这个词"binding"。基本上我无法到达任何特定信息。它叫什么所以我可以实际搜索有关它的更多信息/示例吗?
 
Last edited:

约翰

C#论坛主持人
工作人员
加入
2011年4月23日
消息
1,159
地点
挪威
编程经验
10+
有关使用没有指定属性的绑定进行绑定的更多信息
例如: 数据绑定概述 - WPF
在与上述文章中还讨论了它:
如果您想对此进行任何文章,请在这些文章中进行搜索{绑定}。
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
也许在此阶段甚至有点在这个阶段为我提供了一点。
我不同意。我觉得你已经把自己与WPF的初学者相得益彰,特别是对于原本来自Winforms的人来说。我会鼓励你在Skydiver的例子中研究所有的小比特。如接口,方法,属性以及该性质中的任何内容。一旦您了解拼图,您就可以了解如何将其融合在一起。这可能会带你一段时间才能弄清楚相关文件的一些光线阅读。

请记住,如果您需要帮助理解您没有完全理解的东西,我们就可以帮助并指导您。所以不要害怕问问题,无论他们如何愚蠢或简单。当然,我总是鼓励在论坛上询问问题之前鼓励在Inter Web上寻找一些东西,因为这使我们能够将您与您联系起来的东西,您可以为自己搜索网络。但如果你仍然没有掌握某些东西,请与我们分享,所以我们可以帮助你。

我不想担心提高你的自我来说这一点。大声笑,我不认为我曾经有人在任何公共论坛上获得了公众认可。你看,我实际上认为,通过帮助其他人在他们的主题上帮助其他人来说,您可以对这些论坛的别人有价值,从而为您刷新并花费足够的时间学习和研究,并扩大您对您所写的主题的知识今天的代码。

我知道当有人对不仅仅是代码有很好的理解,但他们正在写的语言,我也可以告诉我有人对他们有良好的伦理伦理,最重要的是,如果他们有可能成为福彩12选5走势图好程序员线。我认为你有这种潜力。当我成为福彩12选5走势图项目经理时,我可能继承了这种直觉。然而,您应该知道,成为福彩12选5走势图更好的程序员的最佳方式之一是帮助别人排除他们的代码,并帮助他们找到解决问题的解决方案。我对你感兴趣的原因;只是因为我争取了愿意学习的任何人,以及你以前表现出极高的兴趣和愿意与你的网格主题。我尊重愿意在这一领域推动自己的人,无论你真的还是为了娱乐。保持它 (y)
 

玻璃灯

众所周知的成员
加入
2019年11月22日
消息
126
编程经验
Beginner
哇,非常感谢您的信心推动!然而,你会发现我的自我倾向于自我贬低的方向,所以它可以随着升级而做 :)

我接近戒烟大多数日子,而且在我辞职的时候我回到第二天时,要学习编程的驱动器让我走向我,我发现它令人惊讶和令人兴奋!但我觉得戒烟的唯一原因是因为很难知道接下来作为自学者的一步(特别是当我反对感觉不可能理解的东西时),我之前没有道路我并试图在一起刮掉福彩12选5走势图很难,所以我倾向于随机反弹主题。我一直在进行进步,一点,所以我想我只需要坚持下去,无论何时看起来有多困难。

你似乎对我的潜力有更多的信心,我做了,我没有大多数情况真的,它真的很高兴地学习这种东西,这就是驱动我的原因,我只是喜欢它。

至于跳伞运动员慷慨的例子,我知道我在那里有一些优秀的材料来获得我的研究,我还没有完成它们。
 

玻璃灯

众所周知的成员
加入
2019年11月22日
消息
126
编程经验
Beginner
我有另福彩12选5走势图关于这条行的问题:

C#:
TextBlock Text="{Binding}"

如果横幅类包含更多,则只需福彩12选5走势图属性,您需要绑定到该属性,而不是仅使用绑定关键字?
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,892
地点
切萨皮克,va.
编程经验
10+
It depends. The binding defaults to the results of calling ToString(). If your implementation of ToString() already maps to the property you are interested in, then do nothing. If you are interested in a different property, obviously you'll need to bind to that property.
 

玻璃灯

众所周知的成员
加入
2019年11月22日
消息
126
编程经验
Beginner
太好了。

我正在尝试使用您的榜样修改/播放。我想做的就是在第福彩12选5走势图横幅下方做另福彩12选5走势图横幅,除了它将显示下福彩12选5走势图字母的字母,所以如果我键入a,我会看到两个"boxes",福彩12选5走势图在另福彩12选5走势图上,福彩12选5走势图在顶部和b底部。

我想到这一切的方式是制作另福彩12选5走势图名单<string>就像你制作的字符列表一样。在Text属性的Setter中,我将按字符复制文本字符串字符,但是在字母表中复制福彩12选5走势图字符。我认为之后,应该重复和修改项目控制才能绑定到其他列表<string>.

我认为这会对吗?
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,892
地点
切萨皮克,va.
编程经验
10+
It will work only if the banner goes infinitely long left to right, then you can stack two ItemsControls on top of each other.

如果你不希望它无限左右,并且希望事情正确包装,以便你得到类似的东西:

C#:
H e l l o
A B C D E
W o r l d
F G H I J
Then you'll need to make the DataTemplate a Border that wraps a vertical StackPanel which then contains two TextBlocks where the first binds to a string representing the character typed in, and the second binds to the alphabet letter in your sequence.
 
最佳 底部