Я работаю в системе выставления счетов и использую DataGrid
для ввода товара. Я хочу, чтобы пользователи могли вводить количества в разных единицах (например, дюймах, футах, метрах) и чтобы это введенное количество конвертировалось в единицы складирования товара. Моей первой мыслью было реализовать IMultiValueConverter
, но я пробовал со вчерашнего дня и не могу понять.
Мой метод Convert работает наверняка, я фактически взял тело, вставил его в другой метод и проверил его вывод. Моя программа дает сбой в методе ConvertBack
, я новичок в C #, и я никогда не видел, чтобы кто-нибудь на самом деле реализовал этот метод, поэтому мне интересно, почему он заставляет меня его реализовывать (полагаю, это из-за моего количества привязка не односторонняя), но мне действительно нужно преобразованное значение, чтобы вернуться к исходным объектам. Свойство Количество.
У меня действительно нет проблем с реализацией метода ConvertBack
, но параметр значения, который передается в метод, является значением, введенным пользователем, а не преобразованным значением, почему это так? Если это не конвертированное значение, по этой причине я не могу понять, как вернуться назад, потому что у меня есть доступ только к тому, что вводит пользователь, а не к требуемым единицам в этом методе.
Я понимаю, что мое понимание конвертеров, вероятно, далеко, но если кто-то может помочь мне понять, где мои мысли здесь, я буду признателен за это, а также за любые возможные обходные пути / решения для моей проблемы.
Заранее спасибо!
Страницы / 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
}