user1070084
user1070084

Reputation: 383

ConvertBack not called on XAML Binding

I'm using a DataGrid to display some shop stock information. Each item can belong to one type of stock.

The relevant entity ('StockEntity') has properties such as:
'ItemId', 'ItemType', 'Grocery', 'Reading', 'Bathroom'.

A couple of example rows in this table would be:
27, 'Grocery', 'Apple', null, null, null
127, 'Reading', null, 'Reading lamp', null, null

I have no control over the database/entity structure.

The DataGrid column is a custom column, containing (amongst others), a TextBox. The DataGrid is bound to an ObservableCollection of StockEntity objects. I want to bind the value of the TextBox to the relevant property. For example, if 'ItemType' = 'Grocery', the TextBox displays the 'Grocery' property. If I change the value in the textbox, it should get written back to the 'Grocery' property.

Here's what I have so far:

XAML:

<TextBox Grid.Column="0" Padding="5" VerticalAlignment="Center" Width="155">
    <TextBox.Text>
        <Binding Path="."
            Converter="{StaticResource StockDataToTextConverter}"
            Mode="TwoWay"
            UpdateSourceTrigger="LostFocus">
        </Binding>
    </TextBox.Text>    
</TextBox>

The converter is simple:

private StockEntity stock;

public object Convert(object value, Type targetType, object parameter, 
    CultureInfo culture)
{
    this.stock = value as StockEntity;
    string text="";

    if(this.stock!=null){
        text = StockModel.GetStockData(this.stock);
    }

    return text;
}

public object ConvertBack(object value, Type targetType, object parameter, 
    CultureInfo culture)
{           
    string info = value as string;

    if(info!=null && this.stock!=null){
        StockModel.SetStockData(ref this.stock, info);
    }

    return stock;
}

The StockModel.Get/SetStockData() methods simply use reflection to get/put the info back into the correct property. The Convert() method works fine: the TextBox displays the correct data. If I edit the value in the TextBox, it just reverts back to the old value. ConvertBack() isn't called.

I think the ConvertBack() method isn't getting called because of the Binding Path=".", but I can't think of another way around this. I also don't know if I can 'save' the bound object in the converter the way I have. It's critical that the value of the TextBox gets written back to the same entity object, to preserve the database connection properties of the entity!

Many thanks.

Upvotes: 0

Views: 1014

Answers (1)

user1070084
user1070084

Reputation: 383

What I really wanted was something like:

<Binding Path={Binding Path="ItemType"} />

This is impossible!

The solution was to wrap the StockEntity object in my own class, and expose a 'binding property', which decided on which stock property to get/set. Instead of having a collection of StockEntity objects, I now have an ObservableCollection of WrapperClass objects to bind the DataGrid to. The wrapper looks something like:

public class WrapperClass{

    public WrapperClass(StockEntity se)
    {
        this._stock = se;
    }

    private StockEntity _stock;
    public stock {
        get { return _stock; }
        set { _stock = value; }
    }

    public string BindingProperty {
        get
        {
            // use reflection to return value
            return StockModel.GetStockData(this._stock);
        }

        set
        {
            // use reflection to set value
            StockModel.SetStockData(ref this._stock);
        }
    }
}

The XAML was then simply:

<Binding Path="StockWrapper.BindingProperty" />

Upvotes: 1

Related Questions