为什么我的背景颜色绑定没有更新?

时间:2015-03-20 18:50:05

标签: c# wpf mvvm data-binding

好的,我确定我的设置正确...

我有一个网格,如下所示:

<Grid Grid.Row="1" Grid.Column="1" Background="{Binding CrewSelBG[1]}">

确定。我有以下数组:

private string[] crewSelBG;
public string[] CrewSelBG
{
    get
    {
        return crewSelBG;
    }
    set
    {
        crewSelBG = value;
        OnPropertyChanged("CrewSelBG");
    }
}

我在我的viewmodel的构造函数中初始化我的数组中的值,如下所示:

CrewSelBG = new string[26];
CrewSelBG = Enumerable.Repeat("#8a008a00", 26).ToArray();

这会将整个阵列初始化为绿色。 (实际上绿色应该是#00000000,但我想看到它被正确绑定)。 我有一个复选框,单击该复选框可激活icommand。这是我的复选框:

<CheckBox Grid.Column="0" IsChecked="{Binding CrewChecked[1]}" Margin="5,0,0,0" Command="{Binding CrewSelectCheck}" CommandParameter="01"/>

它调用的ICommand在这里设置:

private ICommand crewSelectCheck;

public ICommand CrewSelectCheck
{
    get
    {
        if (crewSelectCheck == null)
        {
            crewSelectCheck = new RelayCommand(param => this.CrewSelectCheckEx(param.ToString()), null);
        }
        return crewSelectCheck;
    }
}

public void CrewSelectCheckEx(string p)
{
    if (CrewChecked[Convert.ToInt32(p)])
    {
        CrewSelBG[Convert.ToInt32(p)] = "AliceBlue";//selected
    }
    else
    {
        CrewSelBG[Convert.ToInt32(p)] = "#00000000";
    }
}

OK ...所以......当单击复选框并将其移动到选中状态时,它会触发将线路设置CrewSelBG [1]指向AliceBlue。我在这条线上放了一个断点,确实触发了这条线。我再添加了一行代码,而CrewSelBG [1]确实改为“AliceBlue”。然而,我的网格的背景保持绿色(或者我在构造函数中放置的任何值)。

我不明白为什么它不会更新???我有一个onpropertyraised事件(我尝试添加以下,但没有用:

OnPropertyChanged("CrewSelBG[1]");

这也没有做任何事。)

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

这是ObservableCollection更可取的地方。您应该可以将string[]更改为ObservableCollection<string>并使其正常运行。

你也可以尝试OnPropertyChanged("CrewSelBG"),但即使它有效,也会使你对其元素的所有绑定失效。

答案 1 :(得分:0)

好的,让我们做一些WPF 101.

您实际编写的内容是CrewSelBG的属性,如果替换整个数组对象,它只触发WPF更新机制。这就是它获取初始颜色的原因,因为您创建了一个全新的数组并通过属性设置器进行分配。当然,出于某种原因,你会两次背靠背地做到这一点,但是那个职业保险可能是,要解决这个问题。以后你似乎仍然有用。

现在,仅仅因为你写CrewSelBG[Convert.ToInt32(p)] = "AliceBlue";并不意味着WPF会选择它。怎么可能,你使用该属性的getter(没有通知)并替换某个数组中的某个项目。

WPF实际上为您提供了易于使用的替代品,只需使用ObservableCollection<>即可。它的作用是提供自己的this[]索引器,而在 索引器的设置器中,它通知WPF它已经改变了。它非常完美!

然而,这并不神奇 - 你可以轻松地自己写出来。您可以使用INotifyPropertyChanged来提供索引通知程序,而不是INotifyCollectionChanged接口,而{{3}}接口只提供一个索引通知程序,因此您只能告诉WPF您的集合中的索引已更改。

只是为了让它不受影响,你有很多&#34;我在我的代码中添加了...#34;和#34;我试过......并且没有工作&#34;在你的帖子和评论中,这让我相信你随机输入随机行。 ObservableCollection<> 工作。除了绑定之外,您还必须确保设置了正确的DataContext。如果你走INotifyCollectionChanged路线,你还必须确保从一开始就通知适当的背景 - 即你不会把它放在你的CrewSelectCheckEx功能中。

答案 2 :(得分:0)

问题是您正在更改CrewSelBG数组中的值,而不是更改数组。因此,未调用OnPropertyChanged方法,并且不会通知UI更改。要解决此问题,只需在更改值时手动调用OnPropertyChanged方法,如下所示:

public void CrewSelectCheckEx(string p)
{
    if (CrewChecked[Convert.ToInt32(p)])
    {
        CrewSelBG[Convert.ToInt32(p)] = "AliceBlue";//selected
    }
    else
    {
        CrewSelBG[Convert.ToInt32(p)] = "#00000000";
    }
    OnPropertyChanged("CrewSelBG");
}