多项式函数的用户输入
User Input for polynomial functions
我需要创建一个应用程序,用户可以在其中输入不同的多项式函数。首先,用户必须 select 一定等级的多项式函数(0 到 10 之间)。在 selected 等级的基础上,应该出现不同数量的文本框,用户可以在其中指定系数的值。例如,用户 select 的成绩为“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-2 个可能对此很方便的额外内容)
使用Text="{Binding Value}"
绑定到VM中的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>
看起来像这样(没有成绩文本框,只有右边的东西)
编辑
要适当调整系数的数量,需要一点逻辑,但首先 -> 适当地重命名属性并定义它们可能的值(这有助于为属性创建适当的逻辑)
AvailableGrades = 0, 1, 2 ... 10
SelectedGrade ∈ {0, 1, 2 ... 10}
Coefficients = a(0), a(1) ... a(SelectedGrade)
//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); }
}
}
我需要创建一个应用程序,用户可以在其中输入不同的多项式函数。首先,用户必须 select 一定等级的多项式函数(0 到 10 之间)。在 selected 等级的基础上,应该出现不同数量的文本框,用户可以在其中指定系数的值。例如,用户 select 的成绩为“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-2 个可能对此很方便的额外内容)
使用Text="{Binding Value}"
绑定到VM中的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>
看起来像这样(没有成绩文本框,只有右边的东西)
编辑
要适当调整系数的数量,需要一点逻辑,但首先 -> 适当地重命名属性并定义它们可能的值(这有助于为属性创建适当的逻辑)
AvailableGrades = 0, 1, 2 ... 10
SelectedGrade ∈ {0, 1, 2 ... 10}
Coefficients = a(0), a(1) ... a(SelectedGrade)
//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); }
}
}