Пользовательский элемент управления C#, который может содержать другие Средства управления (при использовании его)

На момент написания статьи никто не обращался к 32-битным или 64-битным кодированным WAV.

Следующий код обрабатывает 16/32/64 бит и моно / стерео:

static bool readWav( string filename, out float[] L, out float[] R )
{
    L = R = null;
    //float [] left = new float[1];

    //float [] right;
    try {
        using (FileStream fs = File.Open(filename,FileMode.Open))
        {
            BinaryReader reader = new BinaryReader(fs);

            // chunk 0
            int chunkID       = reader.ReadInt32();
            int fileSize      = reader.ReadInt32();
            int riffType      = reader.ReadInt32();


            // chunk 1
            int fmtID         = reader.ReadInt32();
            int fmtSize       = reader.ReadInt32(); // bytes for this chunk
            int fmtCode       = reader.ReadInt16();
            int channels      = reader.ReadInt16();
            int sampleRate    = reader.ReadInt32();
            int byteRate      = reader.ReadInt32();
            int fmtBlockAlign = reader.ReadInt16();
            int bitDepth      = reader.ReadInt16();

            if (fmtSize == 18)
            {
                // Read any extra values
                int fmtExtraSize = reader.ReadInt16();
                reader.ReadBytes(fmtExtraSize);
            }

            // chunk 2
            int dataID = reader.ReadInt32();
            int bytes = reader.ReadInt32();

            // DATA!
            byte[] byteArray = reader.ReadBytes(bytes);

            int bytesForSamp = bitDepth/8;
            int samps = bytes / bytesForSamp;


            float[] asFloat = null;
            switch( bitDepth ) {
                case 64:
                    double[] 
                    asDouble          = new double[samps];  
                    Buffer.BlockCopy(byteArray, 0, asDouble, 0, bytes);
                    asFloat = Array.ConvertAll( asDouble, e => (float)e );
                    break;
                case 32:
                    asFloat           = new float[samps];   
                    Buffer.BlockCopy(byteArray, 0, asFloat, 0, bytes);
                    break;
                case 16:
                    Int16 [] 
                    asInt16           = new Int16[samps];   
                    Buffer.BlockCopy(byteArray, 0, asInt16, 0, bytes);
                    asFloat = Array.ConvertAll( asInt16, e => e / (float)Int16.MaxValue );
                    break;
                default:
                    return false;
            }

            switch( channels ) {
            case 1:
                L = asFloat;
                R = null;
                return true;
            case 2:
                L = new float[samps];
                R = new float[samps];
                for( int i=0, s=0; i<samps; i++ ) {
                    L[i] = asFloat[s++];
                    R[i] = asFloat[s++];
                }
                return true;
            default:
                return false;
            }
        }
    }
    catch {
            Debug.Log( "...Failed to load note: " + filename );
            return false;
            //left = new float[ 1 ]{ 0f };
    }

    return false;
}
6
задан Michael Niemand 9 June 2009 в 13:33
поделиться

3 ответа

Вот пример одного из способов сделать то, что вы хотите:

Во-первых, код - UserControl1.xaml.cs

public partial class UserControl1 : UserControl
{
    public static readonly DependencyProperty MyContentProperty =
        DependencyProperty.Register("MyContent", typeof(object), typeof(UserControl1));


    public UserControl1()
    {
        InitializeComponent();
    }

    public object MyContent
    {
        get { return GetValue(MyContentProperty); }
        set { SetValue(MyContentProperty, value); }
    }
}

И XAML пользовательского элемента управления - UserControl1.xaml

<UserControl x:Class="InCtrl.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300" Name="MyCtrl">
    <StackPanel>
        <Button Content="Up"/>
        <ContentPresenter Content="{Binding ElementName=MyCtrl, Path=MyContent}"/>
        <Button Content="Down"/>
    </StackPanel>
</UserControl>

И, наконец, xaml для использования нашего замечательного нового элемента управления:

<Window x:Class="InCtrl.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:me="clr-namespace:InCtrl"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <me:UserControl1>
            <me:UserControl1.MyContent>
                <Button Content="Middle"/>
            </me:UserControl1.MyContent>
        </me:UserControl1>
    </Grid>
</Window>
8
ответ дан 10 December 2019 в 02:52
поделиться

Мне сложно понять ваш вопрос, но я думаю, что вы описываете ItemsControl , использующий DataTemplates для отображения содержимого (предположительно) ObservableCollection (T) .

1
ответ дан 10 December 2019 в 02:52
поделиться

UserControl может быть не лучшим способом сделать это. Вы хотите добавить украшения вокруг содержимого, что в основном и делает Border: у него есть дочерний элемент и он добавляет свой собственный материал по краям.

Посмотрите на класс Decorator, от которого происходит Border. Если вы создадите своего собственного потомка Border, вы легко сможете делать то, что хотите. Однако я считаю, что это потребует написания кода, а не XAML.

Вы все равно можете захотеть сделать UserControl для обертывания кнопок внизу, чтобы вы могли использовать визуальный конструктор для части процесса. Но Decorator был бы хорошим способом склеить части вместе и позволить пользовательский контент.

0
ответ дан 10 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: