停止在列表框中选择的项目

时间:2011-11-10 04:21:46

标签: silverlight

我在Silverlight中有一个ListBox。我想验证用户正在做什么,并在当前项无效时停止选择其他项。这是因为我在编辑窗格中显示其他字段,这些字段对应于ListBox中选择的项目。

我该怎么做?这就是我现在所拥有的,

<ListBox SelectedItem="{Binding SelectedTemplate, Mode=TwoWay}" />
</ListBox>

viewmodel看起来像这样,

public EmailTemplateEntity SelectedTemplate
    {
        get { return selectedTemplate; }
        set 
        {
            if (not valid)
            {
                RaisePropertyChanged(this, x => x.SelectedTemplate); // to reset it to the previous value
            }
            else
            {
                selectedTemplate = value;
            }
        }
    }

但它不起作用。如果getter落入无效代码中,则会调用getter,但所选项目是您选择的项目而不是之前的项目。

更新:

所以我在这里编写了一个WPF应用程序,

<ListBox SelectedValuePath="Content" SelectedValue="{Binding SelectedItem, Mode=TwoWay}">
        <ListBoxItem>Test</ListBoxItem>
        <ListBoxItem>Test1</ListBoxItem>
        <ListBoxItem>Test2</ListBoxItem>
        <ListBoxItem>Test3</ListBoxItem>
        <ListBoxItem>Test4</ListBoxItem>
</ListBox>

和viewmodel,

public class ViewModel : INotifyPropertyChanged
{
    public string SelectedItem
    {
        get
        {
            return "Test1";
        }
        set
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

我希望只允许选择项目Test1,但这也是一样的。

如果我在viewmodel中将项目设为字符串列表,并将itemssource绑定到该列表,则同样适用。

使用snoop我得到一个关于这个问题的提示。 SelectedValue设置正确,但控件有一个名为'SelectedItems'的列表,这是错误设置的。这是一个只读字段。

2 个答案:

答案 0 :(得分:1)

您需要在设置值之前添加验证到您的支持字段,然后通知对UI的更改。

public EmailTemplateEntity SelectedTemplate
{
    get { return selectedTemplate; }
    set 
    {
        // if value is valid then assign the value to your backing field.
        if (IsValid(value))
        {
            selectedTemplate = value;
        }

        // notify changed back to UI, if value is value new selected value is apply, if value is invalid then the value of your backing field is not change and old value is notify to UI.
        RaisePropertyChanged(this, x => x.SelectedTemplate);
    }
}

private bool IsValue(EmailTemplateEntity entity)
{
    // do validation here.
}

答案 1 :(得分:0)

这一定是一个时间问题,更多的是“订单”问题。如果我这样做,

<ListBox Name="ListBox" SelectedValuePath="Content" ItemsSource="{Binding Items}" SelectionChanged="ListBox_SelectionChanged">
</ListBox>

背后有代码,

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    ListBox.SelectedItem = "Item2";
}

然后它有效。如果我们绑定到SelectedValue,则ListBox_SelectionChanged事件在ViewModel中的setter和getter之后触发。它必须与我们在完成所有其他内部事务之后在最后设置SelectedItem有关。