簡體   English   中英

轉換器是從DataGrid而不是綁定對象中獲取價值的?

[英]Converter getting value from DataGrid instead of bound object?

我利用綁定到數據對象的DataGridTextColumn來顯示應用程序中的各種度量。 我正在嘗試實現一個功能,該功能允許以不同的單位顯示測量結果,並認為綁定中的轉換器可能是我最好的選擇。

這對於大多數應用程序來說效果很好,但是我在DataGrid中有另一個字段,用戶可以在其中編輯該字段的值。 在這種情況下,我有兩種方法進行數據綁定,該方法將用戶(例如華氏度)的輸入值轉換回數據對象的默認單位(Celsius)。

我希望轉換器從數據對象中檢索Celcius中的值,進行轉換,然后將此值(以華氏度表示)發送到DataGridTextColumn。 但是,在數據對象上設置值並通知PropertyChanged之后,不會調用該屬性的“ get”方法。 相反,Convert似乎是從DataGridTextColumn獲取用戶輸入的值(以華氏度表示)。

這是正常的行為嗎?如果是,是否有辦法強制將Convert始終返回到數據對象以獲取其值?

一些幫助的片段:

<Window.Resources>
    <myProject:ConvertMetricValuesToEnglish x:Key="ValueMToE" />
</Window.Resources>
.
.
.
<DataGridTextColumn x:Name="maxCol" Header="Maximum" Width="100">
    <DataGridTextColumn.Binding>
        <MultiBinding Mode="TwoWay" StringFormat='0.#####' Converter="{StaticResource ValueMToE}" >
            <Binding Path="UserMax" Mode="TwoWay" />
            <Binding Path="Unit" Mode="OneWay" />
        </MultiBinding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

轉換器方法:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    if (values.Length != 2)
    {
        return null;
    }
    if (values[0].GetType() != typeof(double) || values[1].GetType() != typeof(string))
    {
        return values[0];
    }
    double d = (double)values[0];
    string s = (string)values[1];

    return ConvertValueToEnglish(d, s);
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
    return new object[] { StringToDouble((string)value), Binding.DoNothing };
}

由於在ConvertBack中可用的信息有限,因此我在設置器中執行了“ ConvertBack”轉換:

    private double? _userMax;
    public double UserMax
    {
        get
        {
            if (_userMax == null)
            {
                _userMax = Max;
            }

            return (double)_userMax;
        }
        set
        {
            if (Metric)
            {
                if (value == _userMax)
                {
                    return;
                }
                _userMax = value;
            }
            else
            {
                double num = ConvertValueToMetric(value, _unit);
                if (num == _userMax)
                {
                    return;
                }
                _userMax = num;
            }
            OnPropertyChanged("UserMax");
        }
    }

編輯:這是一個演示該問題的示例項目的鏈接。 左列是用戶可編輯的,代表用戶看到/編輯的數據。 右列顯示在用戶進行更改時實際存儲的基礎值(此值永遠不會更改)。

如果您在左列中修改了一個值,然后在該行中“制表符”或選擇了另一列,則可以看到該值與您輸入的值發生了變化。 但是當該行失去焦點時,它會變回原樣。 通過設置斷點,您可以看到,當單元格本身失去焦點時,首先使用DependencyProperty.UnsetValue's調用Convert方法,然后調用Unit的get方法,然后再次使用帶有DataGrid值的Convert方法。

TempConverter.zip

我能夠自己制定解決方案。 問題在於,直到DataGrid中的整個行都失去焦點之前,才更新源數據對象。 為了解決這個問題,我將一個TextBox作為ControlTemplate應用於該單元格,並設置了一個事件以在TextBox失去焦點時觸發UpdateSource。

XAML:

<DataGridTextColumn x:Name="maxCol" Header="Maximum" Width="100">
    <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <TextBox LostFocus="TextBlock_LostFocus">
                            <TextBox.Text>
                                <MultiBinding StringFormat='0.#####' Converter="{StaticResource ValueMToE}" UpdateSourceTrigger="Explicit">
                                    <Binding Path="UserMax" Mode="TwoWay" />
                                    <Binding Path="Unit" Mode="OneWay" />
                                </MultiBinding>
                            </TextBox.Text>
                        </TextBox>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

事件處理程序:

private void TextBlock_LostFocus(object sender, RoutedEventArgs e)
{
    TextBox b = sender as TextBox;
    if (b == null)
    {
        return;
    }
    MultiBindingExpression mb = BindingOperations.GetMultiBindingExpression(b, TextBox.TextProperty);
    mb.UpdateSource();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM