【问题标题】:WPF ListView setting SelectedItemWPF ListView 设置 SelectedItem
【发布时间】:2011-01-18 11:32:19
【问题描述】:

我试图寻找这个问题的答案,但我没有任何运气。基本上我有一个列表视图,它绑定到从视图模型返回的集合。我将列表视图的选定项目绑定到我的列表视图中的一个属性,以执行验证以确保选择了一个项目。问题是有时我想用已经选择的项目之一加载这个列表视图。我希望能够使用我想要选择的对象在我的视图模型上设置属性,并让它自动选择该项目。这没有发生。我的列表视图在没有选择项目的情况下加载。我可以成功地将选定的索引设置为第 0 个索引,那么为什么我不能设置选定的值。列表视图处于单选模式。

这是我的列表视图中的相关代码

<ListView Name="listView1" ItemsSource="{Binding Path=AvailableStyles}" SelectionMode="Single">
            <ListView.SelectedItem>
                <Binding Path="SelectedStyle" ValidatesOnDataErrors="True" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" BindingGroupName="StyleBinding" >

                </Binding>
            </ListView.SelectedItem>
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="StyleImage">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                               <Image Source="800.jpg"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="Style Code" DisplayMemberBinding="{Binding StyleCode}"/>
                    <GridViewColumn Header="Style Name" DisplayMemberBinding="{Binding StyleName}"/>
                </GridView>
            </ListView.View>
        </ListView>

这是我的视图模型中的相关代码

public class StyleChooserController : BaseController, IDataErrorInfo, INotifyPropertyChanged
{
    private IList<Style> availableStyles;
    private Style selectedStyle;

    public IList<Style> AvailableStyles 
    {
        get { return availableStyles; }
        set
        {
            if (value == availableStyles)
                return;

            availableStyles = value;

            OnPropertyChanged("AvailableStyles");
        }
    }
    public Style SelectedStyle 
    {
        get { return selectedStyle; }
        set
        {
            //if (value == selectedStyle)
            //    return;

            selectedStyle = value;

            OnPropertyChanged("SelectedStyle");
        }
    }

    public StyleChooserController()
    {
        AvailableStyles = StyleService.GetStyleByVenue(1);

        if (ApplicationContext.CurrentStyle != null)
        {
            SelectedStyle = ApplicationContext.CurrentStyle;
        }
    }

    public string Error
    {
        get { return null; }
    }

    public string this[string columnName]
    {
        get
        {
            string error = string.Empty;
            if (columnName == "SelectedStyle")
            {
                if (SelectedStyle == null)
                {
                    error = "required";
                }
            }

            return error;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }
    }

}

我应该注意,这里引用的“样式”与 WPF 无关。这是一个业务对象。我真的在寻找一种不会破坏 MVVM 模式的解决方案,但我愿意让一些功能正常运行。我试图遍历 Listview.Items 列表只是为了手动设置它,但是当我尝试时它总是空的。任何帮助表示赞赏。

编辑:我更新了代码以使用 INotifyPropertyChanged。它仍然无法正常工作。任何其他建议 第二次编辑:我添加了 UpdateSourceTrigger="PropertyChanged"。那仍然没有用。

谢谢

【问题讨论】:

    标签: wpf listview wpf-controls selecteditem


    【解决方案1】:

    您的问题很可能是因为您的SelectedItem Style 与ItemsSource 中的AvailableStyles 中的匹配实例不同的Style 实例。

    您需要做的是在您的 Style 类中提供您对相等性的具体定义:

    public class Style: IEquatable<Style>
    {
        public string StyleCode { get; set; }
        public string StyleName { get; set; }
        public virtual bool Equals(Style other)
        {
            return this.StyleCode == other.StyleCode;
        }
    
        public override bool Equals(object obj)
        {
            return Equals(obj as Style);
        }
    }
    

    【讨论】:

    • 太棒了...这确实有效。有没有更好的方法我不知道?这不是一个糟糕的解决方案,但它让我觉得我做错了什么。我制作单独属性的主要原因是能够验证它是否在视图模型中被选中。再次感谢您的帮助。
    • 你的方法很好。像这样实现 IEquatable 是模型对象的好习惯。您唯一的替代方法是确保 SelectedItem 对象实例包含在 ItemsSource 集合中(引用相等)。这可能需要在您的应用程序中使用不同的方法来加载对象。
    【解决方案2】:

    嗯...您似乎忘记为 SelectedStyle 属性实现 INotifyPropertyChanged...

    【讨论】:

    • 感谢您指出这一点。我确实尝试过,但它仍然无法正常工作。我将自动实现的属性更改为具有显式私有变量并在 set 属性中触发事件。仍然不会突出显示或更改所选值。这很奇怪,因为当你建议我认为它肯定会起作用时。我进行了调试以确保事件正在触发。
    • 我刚刚走近一点,处理程序为空,因此它没有连接事件。我不确定为什么。我认为通过指定绑定是自动的。我很抱歉,因为这是新事物,但感谢您的帮助。
    猜你喜欢
    • 2011-02-06
    • 2023-04-06
    • 1970-01-01
    • 2023-03-09
    • 2013-10-09
    • 1970-01-01
    • 2018-07-07
    • 2023-03-25
    • 2015-07-11
    相关资源
    最近更新 更多