问题 动态创建文本块和网格

玻璃杯

知名会员
已加入
2019年11月22日
留言内容
126
编程经验
Beginner
这似乎毫无意义,但我'd like to know if this is possible and practice doing it.

我想输入一个文本框,并将文本镜像到表单上,例如在文本框下方。我不希望将文本块绑定到字符串属性,即使这将完全按照我刚才的描述进行。我希望镜像到表单上的单词由每个字母的单独网格列中的单个文本块组成,这将进入主网格中的一个单元格,可能位于文本框下方的表单中心。

所以如果我输入单词"Hello"在文本框中,将创建一个五列网格,在每一列中将是一个文本块,显示单词的单个字母"Hello"。我很难考虑尝试此操作,因为我不知道如何在不显式创建和命名控件的情况下完成此操作。我想用一个"foreach(stringName中的char c)"循环中,每当创建一列,就创建一个文本块,将其添加到网格中并更改为适当的字母,但是也许我在考虑那个错误?我该怎么做?

谢谢
 

玻璃杯

知名会员
已加入
2019年11月22日
留言内容
126
编程经验
Beginner
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.

哦,我没想到要在边界添加第二个标签,对此我感到有些愚蠢。我要解决这个问题,看看我能否实现。
 

玻璃杯

知名会员
已加入
2019年11月22日
留言内容
126
编程经验
Beginner
我的想法没有用。代码如下:

MainWindow.xaml:
<Window x:Class="BannerApp.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:BannerApp"
        mc:Ignorable="d"
        Title="MainWindow" 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">
                        <StackPanel>
                            <TextBlock Text="{Binding Chars}"
                                   FontSize="20"
                                   Margin="10"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Bottom"/>
                            <TextBlock Text="{Binding NextChars}"
                                   FontSize="20"
                                   Margin="10"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Bottom"/>
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</Window>

BannerViewModel.cs:
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;

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

        public string Text
        {
            get => _banner.Text;

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

        private void UpdateNextChars()
        {
            NextChars = Chars;

            for (int i = 0; i < Chars.Count; i++)
            {
                NextChars[i] = Chars[i] switch
                {
                    "a" => "b",
                    "b" => "c",
                    "c" => "d",
                    "d" => "e",
                    "e" => "f",
                    "f" => "g",
                    "g" => "h",
                    "h" => "i",
                    "i" => "j",
                    "j" => "k",
                    "k" => "l",
                    "l" => "m",
                    "m" => "n",
                    "n" => "o",
                    "o" => "p",
                    "p" => "q",
                    "q" => "r",
                    "r" => "s",
                    "s" => "t",
                    "t" => "u",
                    "u" => "v",
                    "v" => "w",
                    "w" => "x",
                    "x" => "y",
                    "y" => "z",
                    "z" => "a",
                    _ => " "
                };
            }
        }

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

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

        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged([CallerMemberName] string info = "")
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
    }
}

MainWindow.xaml.cs和Banner.cs尚未修改。我的想法不涉及更改Banner类中的任何内容,也许那是我的错误的一部分?

编辑:我只是有一个天才的想法,实际上在这篇文章中包括什么代码 :)

堆栈面板被扩展并且是其高度的两倍,但是大写字母下方的区域保留为空。视觉上所有发生的是"boxes" are now "rectangles".
 
Last edited:

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,605
地点
弗吉尼亚州切萨皮克
编程经验
10+
我还没有机会仔细查看或尝试运行您的代码,但是这些对我来说很突出:

这不会复制列表的内容,它只是一个参考。
C#:
NextChars = Chars;

您需要先更新数据,然后再发送通知,否则那些订阅更改的通知将选择旧数据:
C#:
_banner.Text = value;
NotifyPropertyChanged();
NotifyPropertyChanged("Chars");
NotifyPropertyChanged("NextChars");
UpdateNextChars();
 

玻璃杯

知名会员
已加入
2019年11月22日
留言内容
126
编程经验
Beginner
好的,我这样修改了它们:

C#:
get => _banner.Text;
set
{
    _banner.Text = value;
    NotifyPropertyChanged();
    NotifyPropertyChanged("Chars");
    UpdateNextChars();
    NotifyPropertyChanged("NextChars");
}

C#:
for (int i = 0; i < Chars.Count; i++)
{
    NextChars.Add(Chars[i]);
}

从外观上看,运行该应用程序时没有任何更改。这是一张照片:

GPDNlPsuNf.png
 

玻璃杯

知名会员
已加入
2019年11月22日
留言内容
126
编程经验
Beginner
忘记我的最后一个问题,那又如何呢?我如何添加一个额外的"element"(我不知道正确的术语)。

Untitled.png


如果您看上面的图片,我如何添加一个额外的图片"square"最后将占用两个"rows"。它的内容将是一个简单的绑定,我对此不需要任何帮助,我只需要创建这种类型的布局的帮助即可。如果横幅中有文字,则末尾的正方形将始终可见,并且将始终位于右侧。我希望这仅需要模板的简单修改。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,979
地点
英国
编程经验
10+
 

玻璃杯

知名会员
已加入
2019年11月22日
留言内容
126
编程经验
Beginner
刚开始我不明白你的意思,但是由于某种原因"Hello, World!"再次,我有了灵感,可以肯定的是我解决了这个问题。不幸的是,我在确认之前遇到了另一个问题,但这是另一个帖子的问题(我将在30分钟左右的时间内完成)。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,979
地点
英国
编程经验
10+
好吧,如果该链接解决了您的问题,请编辑您的原始帖子,并将此主题标记为已回答。 如果 我有时间,请看一下您的下一个问题。
 

玻璃杯

知名会员
已加入
2019年11月22日
留言内容
126
编程经验
Beginner
我不知道它是否解决了问题,我必须先解决另一个问题,然后我才能说出来。

我没意识到我可以将线程标记为已解决,我将遍历所有已解决的问题,甚至还没有这样做。你能告诉我怎么做吗?
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,979
地点
英国
编程经验
10+
我不知道它是否解决了问题,我必须先解决另一个问题,然后我才能说出来。
另一个问题是什么?如果与当前主题无关,我们可以稍后作为主持人要求拆分主题。

我将遍历所有帖子,并针对所有已解决的问题进行该操作,直到现在我还没有这样做。你能告诉我怎么做吗?
此屏幕快照显示了去向和操作方法。

在您主题的第一条帖子的报告链接旁边有一个编辑链接。编辑它,并将前缀更改为“已回答”。我没有看到有关您的主题的编辑链接,因此我无法担任主持人,因此无法为您更改它。

截屏 :

屏幕截图_87.jpg

就像我可以在这里发表自己的文章一样。这是编辑主题时前缀的位置:
截图_88.jpg


更改主题的状态前缀时,请勿更改主题中的任何内容。
 
Last edited:

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,979
地点
英国
编程经验
10+
还是那样。我想无论如何减轻您的工作量。 (y)

我之所以建议这样做的原因是,这些主题可能并非无关紧要,如果我不问,我也不知道。
 

玻璃杯

知名会员
已加入
2019年11月22日
留言内容
126
编程经验
Beginner
对于想到的每个新主题,您都可以轻松自己启动新主题 ;)

我确实尝试这样做 思考 我已经?有时似乎我已经挂了一个线程,但这仅是因为我计划在某个时候返回它。有时候我会得到一个我做不了的答案,但是我知道,如果我在学习/练习了一些其他东西之后再回过头来,我将能够更好地掌握它。

不幸的是,史波林斯在报告旁没有编辑选项,我认为这有时间限制,最终会消失。我将浏览我的线程,找到已完成的线程,并添加一条帖子,这样,MOD便可以处理它。那样行吗?
 

玻璃杯

知名会员
已加入
2019年11月22日
留言内容
126
编程经验
Beginner
对于想到的每个新主题,您都可以轻松自己启动新主题 ;)

如果您愿意,我可以给您发送可以标记为已解决的线程的标题,因为我自己做不到。我正在尝试遵循规则,但并没有因为使线程挂起而被mods告知,所以我想知道是否有人真正在乎。
 
最佳 底部