C# 多项式函数的用户输入
我需要创建一个应用程序,用户可以输入不同的多项式函数。首先,用户必须选择多项式函数的某一等级(介于0和10之间)。根据所选等级,应出现不同数量的文本框,用户可在其中指定系数的值。例如,用户选择等级“4”->显示5个文本框。应该是这样的: a4_uuuuuuuuuuuuuuua2_uuuuuuuuuuuua1_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu ___:表示单个文本框 在使用ItemsControl时,我也很难将文本框水平对齐。 我还想保存用户在我的ViewModel中输入的值。我已经尝试了很多东西,但我不知道怎么做。这是我目前的代码:C# 多项式函数的用户输入,c#,wpf,textbox,viewmodel,C#,Wpf,Textbox,Viewmodel,我需要创建一个应用程序,用户可以输入不同的多项式函数。首先,用户必须选择多项式函数的某一等级(介于0和10之间)。根据所选等级,应出现不同数量的文本框,用户可在其中指定系数的值。例如,用户选择等级“4”->显示5个文本框。应该是这样的: a4_uuuuuuuuuuuuuuua2_uuuuuuuuuuuua1_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu ___:表示单个文本框 在使用ItemsControl时,我也很难将文本框水平对
<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();
});
}
}
公共可观测集合选定交易
{
得到
{
ObservableCollection newCol=新的ObservableCollection();
for(int i=0;i
{
函数newPolyFunc=新的多函数(此为系数);
Functions.Add(newPolyFunc);
计算点();
});
}
}
根据这些评论,我将提供一个小示例,说明如何实现这一点(我添加了1-2个额外功能,可能会很方便)
使用Text=“{Binding Value}”
绑定到VM中的值
使用Wrappanel
水平显示
(可选)使用alternationandex
标记系数
(可选)更改流动方向
,使其像绘制草图一样显示
<!-- 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。。。十, 选定贸易∈ {0,1,2…10} 系数=a(0),a(1)。。。a(选定级别)
//不幸的是,无法使用值类型并绑定到它,因为它没有Getter/Setter,因此我们需要一个小包装器
公共类ValueTypeAsClass
{
公共T值{get;set;}
公共静态隐式运算符ValueTypeAsClass(tV)
{
返回新的ValueTypeAsClass{Value=v};
}
公共静态隐式运算符T(ValueTypeAsClass v)
{
返回v.值;
}
}
//选择等级的成员变量
私有整数_selectedGrade=0;
//系数列表(从SelectedGrade重命名)
公共ObservableCollection系数{get;set;}=new ObservableCollection(){0d};
//可从组合框中选择的可用(有效)等级
public List AvailableGrades{get;private set;}=Enumerable.Range(0,11).ToList();
//当前选择的梯度,带有调整系数量的逻辑
公共国际贸易
{
获取{return\u selectedGrade;}
设置
{
_selectedGrade=值;
//清除系数并添加必要的数量
系数.Clear();
对于(int i=0;i),这有助于我为输入设置ItemsControl
样式,并将其绑定到observedcollection
。然后您可以根据需要创建任意多的条目(0-10级)当您将其样式设置正确时,它将显示为您绘制的样式。@LittleBit您对如何水平对齐文本框有什么建议吗?我已经在顶部插入了我的代码。您是在正确的轨道上,但不幸的是文本框的值/文本未绑定到SelectedGrade
。如果您可以指定SelectedGrade
是(List
,ObservableCollection
,其他)我将提供一个示例作为答案。是的,这是一个ObservableCollection非常感谢!这几乎解决了它。我唯一剩下的问题是,如何更改viewModel(ObservableCollection)中系数的值当我在应用程序中更改它们时。我在顶部插入了属性的代码。我会首先将属性重命名为它们所代表的“东西”(例如,SelectedGrade不应该是系数的集合,只需将其命名为“系数”)。当您分离变量时,您可以向SelectedGrade
属性添加一点逻辑,它将按照您的预期工作(请参见答案中的编辑)。如果这符合您的需要,请将其标记为答案:)非常感谢!唯一不起作用的是,当我更改系数时,系数的ObservableCollection似乎不会更新值。我用系数列表视图对其进行了双重检查,但值只是不想更改。@Felixbrandi哦,对了,值类型没有getter/setter,不能直接绑定。i've为ValueTypes添加了一个小包装类。当您将绑定路径=。
更改为绑定值时,它会更新Viewmodel中的系数(您可以像往常一样使用系数,如系数[0]=3d;
等)。如果某个函数不起作用,请尝试复制整个代码。我在向ObservableCollection添加新函数时遇到问题。基本上,所有最新的函数都将替换为我尝试添加到集合中的函数。例如,我向集合中添加了3个不同的函数,但在
//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); }
}
}