0

This is not an easy one.

I have a listbox (elementSelection) and a textblock (elementViewer). elementViewer shows one element of an array, which is selected by elementSelection box. All this works and even if I modify one element in the array programatically the change is reflected in the elementViewer. Here is the code:

public class ArrElem : INotifyPropertyChanged
{
    public ArrElem(double d)
    {
        wert = d;
    }

    private double intwert;
    public double wert
    {
        get { return intwert; }
        set
        {
            intwert = value;
            NotifyPropertyChanged("wert");
        }
    }
    // Declare the PropertyChanged event
    public event PropertyChangedEventHandler PropertyChanged;

    // NotifyPropertyChanged will raise the PropertyChanged event passing the
    // source property that is being updated.
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

private ObservableCollection<ArrElem> arrField = new ObservableCollection<ArrElem>();
public ObservableCollection<ArrElem> Arr { get { return arrField; } set { arrField = value; } }

private ObservableCollection<int> indexArrField = new ObservableCollection<int>();
public ObservableCollection<int> indexArr { get { return indexArrField; } set { indexArrField = value; } }


    public MainWindow()
    {
        Arr.Add(new ArrElem(1.1));
        Arr.Add(new ArrElem(2.2));
        for (int i = 0; i < Arr.Count; i++)
        {
            indexArr.Add(i);
        }

        InitializeComponent();
        DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // this one doesn't show on elementViewer
        //double d = Arr[0].wert + 0.1;
        //Arr.RemoveAt(0);
        //Arr.Insert(0, new ArrElem(d));

        // this one shows on elementViewer
        Arr[0].wert += 0.1;
    }

public class MySpecialMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        int i = int.Parse(values[0].ToString());
        ObservableCollection<ArrElem> arr = values[1] as ObservableCollection<ArrElem>;

        if (arr == null || i >= arr.Count || i < 0)
            return DependencyProperty.UnsetValue;

        return arr[i];
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        object[] ooo = new object[1];
        ooo[0] = DependencyProperty.UnsetValue;
        return ooo;
    }
}



    <local:MySpecialMultiConverter x:Key="multiConverter" />

    <ListBox Name="elementSelection" ItemsSource="{Binding indexArr}"></ListBox>

    <TextBlock Name="elementViewer" Text="{Binding Path=wert}" >
        <TextBlock.DataContext>
            <MultiBinding Converter="{StaticResource multiConverter}">
                <Binding ElementName="elementSelection" Path="SelectedIndex" />
                <Binding Path="Arr" />
            </MultiBinding>
        </TextBlock.DataContext>
    </TextBlock>

Now my problem: As you can see in the code of Button_Click, the changes to an individual ArrElem show up in elementViewer, but if I replace the ArrElem elementViewer doesn't update.

What do I have to change to get an update of elementViewer in both cases?

1 Answer 1

1

I guess that the list box doesn't have a selected item any more after you deleted it from the bound collection. (SelectedIndex == -1). Try setting it after the change:

var selectedIndex = elementSelection.SelectedIndex;
double d = Arr[0].wert + 0.1;
Arr.RemoveAt(0);
Arr.Insert(0, new ArrElem(d));
elementSelection.SelectedIndex = selectedIndex;

BTW: You can bind your TextBlock directly to the SelectedItem property of your ListBox. No need to write a converter.

Sign up to request clarification or add additional context in comments.

8 Comments

No, SelectedIndex doesn't change and it doesn't help to set it again. And no, I can't bind directly to SelectedItem without a converter, because I wouldn't have access to the array element then (or at least I don't know how).
SelectedItem IS the array element.
Sorry, I didn't see this. But it doesn't help, SelectedItem is the element of indexArr and not of Arr. I need this indexArray, because in my app there should be the possibility to select array elements which are not existent at the moment.
Ah, I didn't see that the listbox isn't bound to the same array as you pass to the converter. The problem is, that neither SelectedIndex nor Arr are raising a PropertyChanged event, that's why the binding on the TextBox isn't re-evaluated. Try using elementViewer.GetBindingExpression(TextBox.TextProperty).UpdateTarget();.
GetBindingExpression returns null
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.