开发者

Binding to Array Element Doesn't Update

开发者 https://www.devze.com 2023-02-19 22:10 出处:网络
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 an

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 { g开发者_JAVA技巧et { 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?


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消