我有一个应用程序,用于在高架投影仪上显示歌曲.目前编写的方式是使用文本框的堆栈面板,每个文本框的每一行都显示.还可以选择在每条线上方显示和弦.
我面临的问题是人们经常想要为歌曲文本和和弦文本制作更小或更大的字体.每次更改时,都必须编辑歌曲以再次排列和弦.文本的对齐也会影响和弦的位置.
我正在寻找一种更健壮的方法来将一个和弦与一段文本对齐,并将它保持在相对于它的单词的相同位置.我曾想过使用画布,但不知道如何用正确的单词排列文本.
对于什么最适合这种情况,我有点不知所措,并希望得到任何建议.
解决方法
我认为将Chord和Txt Char一起引用是一个好主意.一个StackPanel可以容纳2个TextBlocks.从那里它只是向外思考.
每一行都可以是一个ItemsControl水平堆叠这些StackPanels.
然后,常规ListBox可以保存这些行.
viewmodels.cs
using System; using System.ComponentModel; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Runtime.CompilerServices; namespace Karaoke { public class ChordData { public ChordData(string chord,int position) { Chord = chord; Position = position; } #region Chord Property private String _chord; public String Chord { get { return _chord; } set { if (value != _chord) _chord = value; } } #endregion Chord Property #region Position Property private int _position; public int Position { get { return _position; } set { if (value != _position) _position = value; } } #endregion Position Property } public class KaraokeChar { public KaraokeChar(char txt) { Txt = txt; Chord = ""; } #region Txt Property private Char _txt; public Char Txt { get { return _txt; } set { if (value != _txt) _txt = value; } } #endregion Txt Property #region Chord Property private String _chord; public String Chord { get { return _chord; } set { if (value != _chord) _chord = value; } } #endregion Chord Property } public class viewmodelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] String propName = null) { // C#6.O // PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propName)); if (PropertyChanged != null) PropertyChanged.Invoke(this,new PropertyChangedEventArgs(propName)); } } public class Itemviewmodel : viewmodelBase { public Itemviewmodel(string txt,List<ChordData> chordList) { foreach (char c in txt) { Line.Add(new KaraokeChar(c)); } foreach (ChordData chord in chordList) { Line[chord.Position].Chord = chord.Chord; } } #region Line Property private ObservableCollection<KaraokeChar> _line = new ObservableCollection<KaraokeChar>(); public ObservableCollection<KaraokeChar> Line { get { return _line; } set { if (value != _line) { _line = value; OnPropertyChanged(); } } } #endregion Line Property } public class Mainviewmodel : viewmodelBase { #region Song Property private ObservableCollection<Itemviewmodel> _song = new ObservableCollection<Itemviewmodel>(); public ObservableCollection<Itemviewmodel> Song { get { return _song; } set { if (value != _song) { _song = value; OnPropertyChanged(); } } } #endregion Song Property #region TextFont Property private int _textFont; public int TextFont { get { return _textFont; } set { if (value != _textFont) { _textFont = value; OnPropertyChanged(); } } } #endregion TextFont Property #region ChordFont Property private int _chordFont; public int ChordFont { get { return _chordFont; } set { if (value != _chordFont) { _chordFont = value; OnPropertyChanged(); } } } #endregion ChordFont Property } }
MainWindow.xaml.cs
using System; using System.IO; using System.Linq; using System.Windows; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Karaoke { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); viewmodel.TextFont = 25; viewmodel.ChordFont = 20; SongData(); } private void SongData() { ObservableCollection<Itemviewmodel> Song = new ObservableCollection<Itemviewmodel>(); Song.Add(new Itemviewmodel("The dog and the cat",new List<ChordData>() { new ChordData("D",0) })); Song.Add(new Itemviewmodel("They take up the middle",new List<ChordData>())); Song.Add(new Itemviewmodel("Where the honey bee hums",new List<ChordData>() { new ChordData("A",8) })); Song.Add(new Itemviewmodel("And Coyote howls",2),new ChordData("D",9) })); viewmodel.song = Song; } // C#6.O // public Mainviewmodel viewmodel => (Mainviewmodel)DataContext; public Mainviewmodel viewmodel { get { return (Mainviewmodel)DataContext; } } } }
MainWindow.xaml
<Window x:Class="Karaoke.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Karaoke" Title="MainWindow" Height="350" Width="525"> <Window.DataContext> <local:Mainviewmodel /> </Window.DataContext> <StackPanel Background="Black"> <Label Foreground="Yellow" FontSize="{Binding TextFont}" HorizontalAlignment="Center">All God's Critters</Label> <ListBox ItemsSource="{Binding Song}" Background="Transparent" BorderBrush="Transparent" Margin="40,0"> <ListBox.ItemTemplate> <DataTemplate> <ItemsControl ItemsSource="{Binding Line}"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Chord}" FontSize="{Binding DataContext.ChordFont,RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Foreground="Purple"/> <TextBlock Text="{Binding Txt}" FontSize="{Binding DataContext.TextFont,RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Foreground="White"/> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel> </Window>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。