Giter VIP home page Giter VIP logo

Comments (5)

IanRawley avatar IanRawley commented on August 29, 2024

This is a common issue with ComboBoxes, and SelectingItemControls in general.

If a change in the ItemsSource causes the current SelectedItem to no longer be in the collection, the ComboBox sets SelectedItem to null. The binding system makes an attempt to push that null to the Source, but rejects the change and sets a DataValidationError. It doesn't notify either side of the binding that this has happened. At this point the ComboBox thinks SelectedItem is null, but the Source thinks it's OldValue. If Source raises a PropertyChanged event realizing this desync has happened, the binding system ignores it because the value on Source hasn't changed. If the ComboBox tries to set the OldValue, the binding system ignores it because the new value matches the one on the Source and so doesn't clear the Validation error.

The only workarounds I know of at present (if you're not using DataValidationErrors) are to either force a change at Source as you are, or keep a record of the old value in the View containing the ComboBox, and if ComboBox.SelectedItem ever becomes null set the old value (or current Source value) directly to ComboBox.SelectedItem.

from avalonia.

CoolCoderSuper avatar CoolCoderSuper commented on August 29, 2024

In this case I set the combo box value and then set the item source

from avalonia.

IanRawley avatar IanRawley commented on August 29, 2024

In this case I set the combo box value and then set the item source

Assuming you're talking ViewModel side, that probably actually makes the problem worse. ViewModel tells ComboBox there's a new SelectedItem. ComboBox checks against the old ItemSource, finds the new SelectedItem is missing, and sets SelectedItem to null. Bindings eat the null, and now ComboBox thinks it's null while the ViewModel thinks it's the right value.

from avalonia.

IanRawley avatar IanRawley commented on August 29, 2024

Basically (as far as I can tell) when ComboBox tries to set SelectedItem to null, something in this block fails and returns false:

// Use the target type converter to convert the value to the target type if necessary.
if (_targetTypeConverter is not null)
{
if (_targetTypeConverter.TryConvert(value, type, ConverterCulture, out var converted))
{
value = converted;
}
else if (FallbackValue != AvaloniaProperty.UnsetValue)
{
value = FallbackValue;
}
else if (IsDataValidationEnabled)
{
var valueString = value?.ToString() ?? "(null)";
var valueTypeName = value?.GetType().FullName ?? "null";
var ex = new InvalidCastException(
$"Could not convert '{valueString}' ({valueTypeName}) to {type}.");
OnDataValidationError(ex);
return false;
}
else
{
return false;
}
}

At this point ComboBox thinks the value is null, and the Binding expression and VM think it is X. If the VM tries to raise PropertyChanged the Binding ignores it because it hasn't, and doesn't push it to the ComboBox. If the ComboBox tries to set SelectedItem back to X the Binding ignores it because that's what it already thinks it is, but it doesn't clear any errors.

I think this is correct on the Source side of things, but when this situation happens there probably needs to be a way for the Binding to reset the bound value on the Target's side. Unfortunately at the moment that probably ends up in infinite loops, so in all likelihood SelectingItemControls need to be smarter about how they handle changes in SelectedItem / ItemsSource but there's a lot going on there and it's pretty messy.

from avalonia.

CoolCoderSuper avatar CoolCoderSuper commented on August 29, 2024

OK, that makes sense because after I update the item source it shows blank in the UI but the ViewModel still has the value.

from avalonia.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.