c# - Virtual Piano UWP C# 中的黑键实现

标签 c# uwp

因此,我挑战自己在 UWP 中制作虚拟钢琴。到目前为止,我已经设法制作了基本的 UI,应该放置键的位置并使用 DataBinding 我生成了所有的白键。

我有 2 个类(class)。 Sound.cs 和 SoundManager.cs

在 Sounds.cs 中,我创建了一个重载构造函数,因此我可以定义名称、颜色、黑键或白键的图像以及音符的音频文件。

 class Sound
{
    public string Name { get; set; }
    public string AudioFile { get; set; }
    public string WhiteImage { get; set; }
    public string BlackImage { get; set; }
    public  KeyColor Color { get; set; }

    public Sound(string name, KeyColor color)
    {
        Name = name;
        Color = color;   

        if(color == KeyColor.Black)
        {
            BlackImage = string.Format("/Assets/Images/{0}.png", color);
            AudioFile = string.Format("/Assets/Audio/{0}.wav", name);
        }
        else if (color == KeyColor.White)
        {
            WhiteImage = string.Format("/Assets/Images/{0}.png", color);
            AudioFile = string.Format("/Assets/Audio/{0}.wav", name);
        }

    }
}

public enum KeyColor
{
    Black,
    White
}

在 SoundManager.cs 中,我有一个名为 getSounds 的方法,我在其中添加了白键和黑键的所有音符列表。

class SoundManager
{

    public static void getSounds(ObservableCollection<Sound> sounds)
    {
        var allSounds = WhiteSounds();
        sounds.Clear();
        allSounds.ForEach(p => sounds.Add(p));
    }


    private static List<Sound> getSounds()
    {
        var sounds = new List<Sound>();

        sounds.Add(new Sound("C1", KeyColor.White));
        sounds.Add(new Sound("C#1", KeyColor.Black));
        sounds.Add(new Sound("D1", KeyColor.White));
        sounds.Add(new Sound("D#1", KeyColor.Black));
        sounds.Add(new Sound("E1", KeyColor.White));
        sounds.Add(new Sound("F1", KeyColor.White));
        sounds.Add(new Sound("F#1", KeyColor.Black));
        sounds.Add(new Sound("G1", KeyColor.White));
        sounds.Add(new Sound("G#1", KeyColor.Black));
        sounds.Add(new Sound("A1", KeyColor.White));
        sounds.Add(new Sound("A#1", KeyColor.Black));
        sounds.Add(new Sound("B1", KeyColor.White));

        return sounds;
    }       
}

在 MainPage.xaml 中,我制作了 GridView,它将显示所有注释,例如可点击的图像。

<GridView Grid.Row="1"
                          Grid.RowSpan="2"
                          Name="SoundGridView"
                          SelectionMode="None"
                          ItemClick="SoundGridView_ItemClick"
                          IsItemClickEnabled="True"
                          ItemsSource="{x:Bind Sounds}"
                          ScrollViewer.VerticalScrollMode="Disabled"
                          ScrollViewer.HorizontalScrollMode="Auto"
                          ScrollViewer.HorizontalScrollBarVisibility="Auto" Margin="0,32,32,0"
                          >

                    <GridView.ItemsPanel>
                        <ItemsPanelTemplate>
                            <ItemsWrapGrid Orientation="Vertical"/>
                        </ItemsPanelTemplate>
                    </GridView.ItemsPanel>


                    <GridView.ItemTemplate >

                        <DataTemplate x:DataType="data:Sound">
                            <RelativePanel>
                                <StackPanel MinHeight="150" MinWidth="50"  Margin="0,0,-12,0" MaxHeight="700" Orientation="Horizontal" >
                                    <Image x:Name="WhiteKeys" Stretch="Fill" MinHeight="150" MinWidth="50" Source="{x:Bind WhiteImage}"/>
                                </StackPanel>
                                <StackPanel>
                                    <Image x:Name="BlackKeys" Stretch="Fill" MinHeight="100" MinWidth="25" Source="{x:Bind BlackImage}"/>
                                </StackPanel>
                            </RelativePanel>                                
                        </DataTemplate>
                    </GridView.ItemTemplate>
                </GridView>

在 MainPage.xaml.cs 中,我创建了所需的 ObservableCollection,这样我就可以在 GridView 中绑定(bind)声音,我还为图像创建了点击事件,因此只要您按下一个键,就会播放一个音符。

public sealed partial class MainPage : Page
{

    private ObservableCollection<Sound> Sounds;    


    public MainPage()
    {
        this.InitializeComponent();
        Sounds = new ObservableCollection<Sound>();
        SoundManager.GetWhiteSounds(Sounds);  

    }        

    private void SoundGridView_ItemClick(object sender, ItemClickEventArgs e)
    {
        var sound = (Sound)e.ClickedItem;
        MyMediaElement.Source = new Uri(this.BaseUri, sound.AudioFile);
    }
}

到目前为止,我的问题是,当我尝试在 RelativePanel 上添加黑键时,它根本无法运行。它让我有这样的期待 Exception Image

但是,当我从相关面板中删除具有黑键图像的 StackPanel 时

                                <StackPanel>
                                    <Image x:Name="BlackKeys" Stretch="Fill" MinHeight="150" MinWidth="50" Source="{x:Bind BlackImage}"/>
                                </StackPanel>

我还删除了 SoundManager.cs 中黑键的声音,只保留白键的声音,应用程序运行但显然,钢琴中没有黑键。

我做错了什么?看来我完全错误地解决了这个问题。那么,有没有办法像这样同时添加白键和黑键:Expectation and Currently

如有任何帮助,我们将不胜感激。

最佳答案

如果使用 x:Bind,ImageSource 需要绑定(bind)到 BitmapImage 的属性而不是字符串,否则它会抛出一个编译时错误。

我们应该能够在 Sound 类中使用 BitmapImage 而不是 string

例如:

internal class Sound
{
    public string Name { get; set; }
    public string AudioFile { get; set; }
    public BitmapImage WhiteImage { get; set; }
    public BitmapImage BlackImage { get; set; }
    public KeyColor Color { get; set; }

    public Sound(string name, KeyColor color)
    {
        Name = name;
        Color = color;

        if (color == KeyColor.Black)
        {
            BlackImage = new BitmapImage(new Uri("ms-appx:///Assets/Images/Black.png"));
            AudioFile = string.Format("ms-appx:///Assets/Audio/22.wav", name);
        }
        else if (color == KeyColor.White)
        {
            WhiteImage = new BitmapImage(new Uri("ms-appx:///Assets/Images/White.PNG"));
            AudioFile = string.Format("ms-appx:///Assets/Audio/11.wav", name);
        }
    }
}

public enum KeyColor
{
    Black,
    White
}

如果想使用字符串类型绑定(bind)Image,我们可以使用Binding代替x:Bind。我们不需要将字符串转换为 BitmapImage,我们应该能够使用 Image.Source 来绑定(bind)字符串。

关于c# - Virtual Piano UWP C# 中的黑键实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42858874/

相关文章:

visual-studio - Windows 10 SDK 不会安装到 Visual Studio

c# - 资源争用

c# - 带有可选参数的扩展方法中的方法解析

c# - 我可以在 WPF 网格中获取标题,从数据模板中获取其行吗?

c# - 将一个 CryptoStream 封装在多个其他 CryptoStream 中会提高安全性吗?

c# - 如何更改 UWP 的复选框背景?

uwp - 如何更改 UWP TabViewItem 角半径?

c# - 在 asp.net 中将字符串转换为日期时间

UWP Mapcontrol - 绑定(bind)到不同 MapElement 的集合并将它们排列在层中

c# - UWP MediaPlayerElement播放音频两次