gpt4 book ai didi

c# - 实现 IMultiValueConverter 以在单位之间进行转换

转载 作者:太空狗 更新时间:2023-10-29 22:20:19 26 4
gpt4 key购买 nike

我正在开发一个发票系统,并且正在使用 DataGrid 进行项目输入。我希望用户能够输入不同单位(例如英寸、英尺、米)的数量,并将输入的数量转换为商品的库存单位。我的第一个想法是实现一个 IMultiValueConverter,但我从昨天开始就一直在尝试,但一直想不出来。

我的 Convert 方法肯定有效,我实际上已经获取了主体,将其插入另一个方法并测试了它的输出。我的程序在 ConvertBack 方法中崩溃,我是 C# 的新手,我从未见过有人实际实现该方法,所以我想知道为什么它迫使我实现它(我是猜测是因为我的 Quantity 绑定(bind)不是单向的),但我实际上需要转换后的值返回到源对象的 Quantity 属性。

我在实现 ConvertBack 方法时确实没有问题,但是传递给该方法的值参数是用户输入的值,而不是转换后的值,这是为什么呢?如果它不是转换后的值,出于这个原因我无法真正弄清楚如何倒退,因为我只能访问用户输入的内容,而不是该方法中所需的单位。

我意识到我对转换器的理解可能还有很长的路要走,但如果有人能帮助我理解我的想法在哪里,我将不胜感激,以及我的问题的任何潜在解决方法/解决方案。

提前致谢!

Pages/PurchaseInvoicePage.xaml

<DataGrid x:Name="ItemsGrid" Grid.Row="2" Grid.ColumnSpan="3" PreviewKeyDown="ItemsGrid_PreviewKeyDown" ItemsSource="{Binding Items}" FontSize="11" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" RowHeaderWidth="0" GridLinesVisibility="None" CanUserResizeRows="False" CanUserResizeColumns="False" CanUserReorderColumns="False">
<DataGrid.Columns>

<DataGridTemplateColumn x:Name="ItemNoColumn" Width="150" Header="Item No." IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Cursor="Arrow" Width="130" BorderThickness="0" Background="Transparent" IsReadOnly="True" Text="{Binding Number}" />
<Image Cursor="Hand" MouseDown="ItemSelectionButton_Click" Width="12" Source="/Images/Icons/SearchBlack.png" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

<!-- question relative xaml starts here -->
<DataGridTextColumn x:Name="QuantityColumn" Width="70" Header="Quantity">
<DataGridTextColumn.Binding>
<MultiBinding Converter="{StaticResource unitConverter}">
<Binding Path="Quantity" />
<Binding Path="Units" Mode="OneWay" />
</MultiBinding>
</DataGridTextColumn.Binding>
</DataGridTextColumn>
<!-- question relative xaml ends here -->

<DataGridTextColumn x:Name="OrderColumn" Width="70" Header="Order" Binding="{Binding QuantityOrdered}" />
<DataGridTextColumn x:Name="BackOrderColumn" Width="70" Header="B/O" Binding="{Binding QuantityBackOrdered}" />
<DataGridTextColumn x:Name="UnitsColumn" Width="60" Header="Units" Binding="{Binding Units}" IsReadOnly="True" />
<DataGridTextColumn x:Name="DescriptionColumn" Width="200" Header="Description" Binding="{Binding Description}" />
<DataGridTextColumn x:Name="PriceColumn" Width="90" Header="Price" Binding="{Binding Price}" />
<DataGridComboBoxColumn x:Name="TaxColumn" Width="50" Header="Tax" SelectedValueBinding="{Binding TaxCodeID}" DisplayMemberPath="Code" SelectedValuePath="ID" />
<DataGridTextColumn x:Name="AmountColumn" Width="90" Header="Amount" Binding="{Binding Amount}" IsReadOnly="True" />
<DataGridTextColumn x:Name="LinkedColumn" Width="90" Header="Linked" Binding="{Binding SalesOrderID}" />
</DataGrid.Columns>
</DataGrid>

Fx/IMultiValueConverter.cs

public class UnitConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameters, CultureInfo culture)
{
double num = 0;
// get the quantity value, and try parsing it
string str = values[0].ToString().ToLower();
bool parsed = double.TryParse(str, out num);

// if it parses, no need to convert, return the value
if (parsed)
return num.ToString();

// if it doesnt parse, get the last character in the value
// this character indicates the units being entered
// this will be either "(inches), f(eet), or m(eters)
string suffix = str.Substring(str.Length - 1);
// get the value, without thhe last character
str = str.Substring(0, str.Length - 1);
// try parsing the value now
parsed = double.TryParse(str, out num);

// if it doesn't parse, the formats incorrect, return 0
if (!parsed)
return (0).ToString();

// get the desired units, (the second value in my multibinding)
string units = values[1].ToString().ToLower();

// if either the entry suffix or the desired units are empty, just return
// the number without converting
if (string.IsNullOrEmpty(suffix) || string.IsNullOrEmpty(units))
return num;

// convert from inches to feet
if (suffix == "\"" && units == "feet")
return (num / 12).ToString();
// convert from inches to meters
else if (suffix == "\"" && units == "meters")
return (num * 0.0254).ToString();
// convert from feet to meters
else if (suffix == "f" && units == "meters")
return (num * 0.3048).ToString();
// convert from meters to feet
else if (suffix == "m" && units == "feet")
return (num / 0.3048).ToString();

// if we reachd this far, the user probably entered something random,
// show an error and return 0
MessageBox.Show("Failed to convert between the two units.");
return (0).ToString();
}

public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
// now this is where my program is crashing,
// for some reason I need to actually implement the ConvertBack function
// but when I try to popup the value being passed to this function,
// it is the value the user entered e.g "20f" and not the converted value
// should it not be the converted value? Why do I even need to implement this
// how should i go backwards from here...
string str = value.ToString();
// MessageBox.Show(str);
return new object[] { 0 }; // btw, I'm only returning one value, because the second binding is oneway

}

最佳答案

有趣的是,就在几周前,我使用 IMultiValueConverter 实现了一个单位转换器。在我去挖掘它看看是否可以帮助你的同时,让我提出一个理论:

也许你翻转了ConvertConvertBack:

Convert:将值从您的模型转换为绑定(bind)源(您的数据网格)

ConvertBack:将用户的输入转换为模型

因此您可以期望在 ConvertBack 函数的参数中提供用户输入。

现在让我看看能否找到那个转换器...

Here是MSDN文档

更新:所以我找到了我的转换器,内存又涌了回来。我遇到了您刚刚遇到的同样问题:我如何将所需的单位传递给转换回函数。老实说,我对我的解决方案不是 100% 满意,但我会与您分享。

我见过的大多数 ValueConverter 实现都是无状态的,因此您可以将它们用作多个绑定(bind)的 StaticResource。我在我的实现中添加了一个单位字段来跟踪单位——这牺牲了它的无状态性:

public class UnitConverter : IMultiValueConverter
{
private string _units;

public object Convert(object[ ] values, Type targetType, object parameter, CultureInfo culture)
{
//Initialize
_units = values[1];
//Convert
}

public object Convert(object[ ] values, Type targetType, object parameter, CultureInfo culture)
{
//Use _units to convert back
}
}

不幸的是,您必须为您使用的每个绑定(bind)创建一个转换器:

<DataGridTextColumn.Binding>
<MultiBinding>
<Binding Path="Quantity" />
<Binding Path="Units" Mode="OneWay" />
<MultiBinding.Converter>
<yourNameSpace:UnitConverter/>
</MultiBinding.Converter>
</MultiBinding>
</DataGridTextColumn.Binding>

我很想看到一个更好的解决方案,但这对我有用。

关于c# - 实现 IMultiValueConverter 以在单位之间进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7078820/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com