Пользовательский ввод для полиномиальных функций - PullRequest
0 голосов
/ 15 апреля 2019

Мне нужно создать приложение, в котором пользователь может вводить различные полиномиальные функции.Сначала пользователь должен выбрать определенный класс полиномиальной функции (от 0 до 10).На основе выбранной оценки должно появиться различное количество текстовых полей, в которых пользователь может указать значения для коэффициентов.Например, пользователь выбирает оценку «4» - появляется 5 текстовых полей.Это должно выглядеть так:

a4 ___ a3___ a2___ a1___ a0___

___: обозначает одно текстовое поле

Я также пытаюсь выровнять текстовые поля по горизонтали при использовании ItemsControl.Я также хочу сохранить значения, введенные пользователем в моей ViewModel.Я уже столько всего перепробовал, но не могу понять, как это сделать.Это мой код:

<ItemsControl ItemsSource="{Binding SelectedGrade}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBox Height="20" Width="100"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

public ObservableCollection<double> SelectedGrade
    {
        get
        {
            ObservableCollection<double> newCol = new ObservableCollection<double>();
            for (int i = 0; i < this.SelectedNum + 1; i++)
            {
                newCol.Add(0);
            }

            this.selectedGrade = newCol;
            return newCol;
        }
        set
        {
            //...
        }
    }


public ICommand AddPolyFuncCommand
    {
        get
        {
            return new Command(obj =>
            {
                Function newPolyFunc = new PolyFunction(this.Coefficients);
                Functions.Add(newPolyFunc);
                CalculatePoints();
            });
        }
    }

1 Ответ

1 голос
/ 15 апреля 2019

В соответствии с комментариями я приведу небольшой пример того, как это можно сделать (я добавил 1-2 дополнения, которые могут быть полезны для этого)

Используйте Text="{Binding Value}" для привязки к значениюв ВМ

Используйте Wrappanel, чтобы отобразить его горизонтально

(необязательно). Используйте AlternationIndex, чтобы обозначить Коэффициенты

(необязательно). Измените FlowDirectionчтобы отобразить его так, как вы нарисовали его

<!-- Combobox to select from the available Grades and store the selected in the SelectedGrade -->
<ComboBox ItemsSource="{Binding AvailableGrades}" SelectedValue="{Binding SelectedGrade}" VerticalAlignment="Top" HorizontalAlignment="Left"/>

<!-- Use Alternationcount to label the coefficients properly and Flowdirection to keep a0 on the right side -->
<ItemsControl ItemsSource="{Binding Coefficients}" AlternationCount="11" FlowDirection="RightToLeft">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <!-- Textbox to enter Coefficient (eg. a0 would be SelectedGrade[0] in code)-->
                <TextBox Text="{Binding Value}" Width="50" VerticalAlignment="Center"/>
                <!-- Labeling of the Coefficient using the AlternationIndex and a String Format -->
                <Label Content="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource TemplatedParent}}" ContentStringFormat="a{0}"/>
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <!--  Use a WrapPanel as ItemsPanel to align the Entries horizontally -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

И выглядит так (без текстового поля оценки, только материал с правой стороны) enter image description here


РЕДАКТИРОВАТЬ

Чтобы правильно настроить количество коэффициентов, требуется немного логики, но сначала -> Переименуйте свойства соответствующим образом и определите их возможное значение (это помогает создать соответствующее значение).логика для свойств)

AvailableGrades = 0, 1, 2 ... 10

SelectedGrade ∈ {0, 1, 2 ... 10}

Коэффициенты = a (0), a (1) ... a (Выбранный класс)

//Unfortunately it is not possible to use a Value Type and bind to it due it has no Getter/Setter therefore we need a little wrapper
public class ValueTypeAsClass<T>
{
    public T Value { get; set; }
    public static implicit operator ValueTypeAsClass<T>(T v)
    {
        return new ValueTypeAsClass<T> { Value = v };
    }
    public static implicit operator T(ValueTypeAsClass<T> v)
    {
        return v.Value;
    }
}

//member variable for select grade
private int _selectedGrade = 0;
//List of Coefficients (renamed from SelectedGrade)
public ObservableCollection<ValueTypeAsClass<double>> Coefficients { get; set; } = new ObservableCollection<ValueTypeAsClass<double>>() { 0d };
//Available (valid) Grades to select from in the ComboBox
public List<int> AvailableGrades { get; private set; } = Enumerable.Range(0, 11).ToList();
//Currently selected grad with logic to adjust the coefficient amount
public int SelectedGrade
{
    get { return _selectedGrade; }
    set
    {
        _selectedGrade = value;
        //Clear Coefficients and add the necessary amount
        Coefficients.Clear();
        for (int i = 0; i <= _selectedGrade; i++) { Coefficients.Add(0); }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...