簡體   English   中英

屬性未正確綁定在ListBox DataTemplate中

[英]Property not bound correctly in ListBox DataTemplate

我在獲取列表框以正確綁定到集合時遇到了一些麻煩。

我將提供框架代碼,然后解釋我想要它做什么。

XAML標記:

<ListBox DataContext="{Binding Foos, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                       ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" 
                       SelectedItem="{Binding Main.SelectedFoo, Mode=TwoWay, 
                       Source={StaticResource Locator}, 
                       UpdateSourceTrigger=PropertyChanged}" 
                       SelectedValue="{Binding Main.SelectedFoo, Source={StaticResource Locator}}"/>


<ListBox ItemsSource="{Binding Main.SelectedFoo.Bars}"  SelectedItem="{Binding Main.SelectedBar}"  >
<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid HorizontalAlignment="Right">
            <!-- The binding requires "{Binding .}" because a path must be explicitly set for Two-Way binding,
                 even though {Binding .} is supposed to be identical to {Binding} -->
                <TextBox Text="{Binding Path=. , UpdateSourceTrigger=PropertyChanged}"  />
         </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

C#ViewModel:

private ObservableCollection<Foo> _barList = new ObservableCollection<Foo>();
private const string BardListPN = "FooList";

public ObservableCollection<Foo> FooList
{
    get { return _fooList; }

    set
    {
        if (_fooList == value)
        {
            return;
        }

        var oldValue = _fooList;
        _fooList = value;

        RaisePropertyChanged(FooListPN);
    }
}

private Foo _selectedFoo;
private const string SelectedFooPN = "SelectedFoo";

public Foo SelectedFoo
{
    get { return _selectedFoo; }

    set
    {
        if (_selectedFoo == value)
        {
            return;
        }

        var oldValue = _selectedFoo;
        _selectedFoo = value;

        // Update bindings, no broadcast
        RaisePropertyChanged(SelectedFooPN);
    }
}

public const string SelectedBarPN = "SelectedBar";
private string _selectedBar = "";

public string SelectedBar
{
    get
    {
        return _selectedBar;
    }

    set
    {
        if (_selectedBar == value)
        {
            return;
        }

        var oldValue = _selectedBar;
        _selectedBar = value;


        // Update bindings, no broadcast
        RaisePropertyChanged(SelectedBarPN);
    }
}

C#模型:

public class Foo
{
    public ICollection<string> Bars
    {
        get { return _bars; }
        set
        {
            _bars= value;
            NotifyPropertyChanged("Bars"); 
            // snipped obvious INotifyPropertyChanged boilerplate code
        }
    }
}

我的問題是,未設置Bar集合中字符串的文本框的任何更改。 當選定的Foo更改為其他Foo並返回時,將顯示原始Bars

有人能告訴我我做錯了什么嗎? 這似乎應該更簡單。 謝謝!

更新:我已經按照Tri Q的建議更改了代碼,但是對文本框所做的更改未反映在屬性本身中。 有任何想法嗎?

在本示例中,我采用的Foo模型類已得到簡化,但是省略的代碼可能是導致問題的根源。 讓我解釋。

Foo還需要實現INotifyPropertyChanged,以便在初始化Bars集合時讓Listbox知道,而這絕對取決於初始化它的時間。

假設您在Foo的構造函數中初始化Bars,將導致Listbox ItemsSource綁定到有效的Bars集合。

public Foo()
{
    Bars = new ObservableCollection<string>();
    ...
}

Buut,如果您這樣做,列表框將不知道Bars集合已被初始化,並且不會更新其來源...

public Foo SelectedFoo
{
    get { return _selectedFoo; }

    set
    {
        if (_selectedFoo == value)
        {
            return;
        }

        var oldValue = _selectedFoo;
        _selectedFoo = value;

        // Update bindings, no broadcast
        RaisePropertyChanged(SelectedFooPN);

        if(_selectedFoo.Bars == null)
        {
            _selectedFoo.Bars = new ObservableCollection<string>();
            // ...
        }
    }
}

另外,您可能需要在XAML中進行一些修改。

首先,默認情況下, Textbox綁定為TwoWay ,因此您無需設置ModePath

<TextBox Text="{Binding UpdateSourceTrigger=PropertyChanged}"  />

其次,為ItemsSource設置Mode="TwoWay"沒有意義。 ItemsSource =“ {Binding Main.SelectedFoo.Bars ,Mode = TwoWay }”

最后,您不需要為DataTemplate設置DataType DataType =“ {x:Type系統:字符串}”

暫無
暫無

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

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