繁体   English   中英

WPF使用SelectedIndex从ViewModel中选择ListBox中的Item

[英]WPF selecting an Item in a ListBox from the ViewModel using SelectedIndex

我是MVVM / WPF的新手,经过几个小时的研究,没有为我的项目找到任何真正有用/可行的答案,我决定试一试,试试这里问。

我想从我的Listbox中选择一个Item,它使用List作为ItemSource。

相关的ViewModel:

public class FavoriteStructureVm : INotifyPropertyChanged
{
    #region
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion

    public ObservableCollection<FavoriteDataVm> Favorites { get; set; }
    public int SelectedIndex { get; set; }
    private FavoriteDataVm _selectedItem;
    public FavoriteDataVm SelectedItem
    {
        set
        {
            _selectedItem = value;
            var item = (FavoriteDataVm)_selectedItem;
            if (item.Type == FavoriteDataType.Add)
            {
                SelectedIndex = 1;
            }
        }
    }
}

ListBox默认包含一些项目,最后一个项目始终是Add类型之一,如果选择,可以添加新项目并默认选择它,如果没有添加新项目,则选择之前选择的项目。 对于Simplicity ,无论是否添加新项目,所选项目都将为1。

无论身在何处,什么我试图更新OnPropertyChanged它并没有在视图然而更新的SelectedIndex,通过添加/插入新FavoriteDataVmObservableCollection<FavoriteDataVm> Favorites中, SelectedIndex视图得到更新。 将新项添加到列表的过程并不总是会发生,但我仍然希望始终更新SelectedIndex

相关的XAML:

<ListBox Name="favMenu" ItemsSource="{Binding Favorites}" SelectionMode="Single" 
                         HorizontalAlignment="Center" VerticalAlignment="Top" 
                         BorderThickness="0" Background="Transparent" Height="{Binding ElementName=window, Path=ActualHeight}" 
                         SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
                         SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}"
                         >
                    <ListBox.Resources>
                        <Style TargetType="ListBoxItem">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="ListBoxItem">
                                        <Border Background="Transparent" SnapsToDevicePixels="true">
                                            <ContentPresenter />
                                        </Border>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </ListBox.Resources>

                    <!--changing default orientation-->
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <VirtualizingStackPanel Orientation="Vertical"/>
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>

                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <Border x:Name="Border"
                                BorderThickness="0" BorderBrush="Black" Background="{x:Null}"
                                Width="60" Height="60" CornerRadius="30" Margin="{Binding Margin}"
                                ToolTip="{Binding Name}">


                                <Image Source="{Binding ImageUri}" Width="60" Height="60" Stretch="UniformToFill">
                                    <Image.Clip>
                                        <EllipseGeometry RadiusX="30" RadiusY="30" Center="30,30"/>
                                    </Image.Clip>
                                </Image>
                            </Border>
                        </DataTemplate>
                    </ListBox.ItemTemplate>

                </ListBox>

我找到了一个解决方法来创建一个虚拟项并删除它,因为添加一些东西似乎更新了视图中的SelectedIndex 我不认为这是一个解决方案,因为它带来了许多缺点。

所以这实际上提出了两个问题:

  • 如何更新ListBox的SelectedIndex

还有一个初学者问题,因为我是MVVM的新手:

  • 这是MVVM的正确实现吗?

如何更新ListBox的SelectedIndex?

您可以通过获取源集合中SelectedItem索引来获取所选索引:

int selectedIndex = (SelectedItem != null && Favorites != null) ? Favorites.IndexOf(SelectedItem) : -1;

您可以通过设置SelectedItem属性来选择项目:

SelectedItem = Favorites[1]; //selects the second item

您不应该同时绑定ListBoxSelectedItemSelectedIndex属性。 这些必须同步。 从您的XAML中删除SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}"

另请注意,如果要动态更新源属性,则需要为此属性引发PropertyChanged以使视图刷新:

private int _selectedIndex;
public int SelectedIndex
{
    get { return _selectedIndex; }
    set { _selectedIndex = value; OnPropertyChanged("SelectedIndex"); }
}

private FavoriteDataVm _selectedItem;
public FavoriteDataVm SelectedItem
{
    set
    {
        _selectedItem = value;
        OnPropertyChanged("SelectedItem");
    }
}

您没有更新SelectedIndex声明应如下所示

     private int _selectedIndex ;
     public int SelectedIndex{ 
     get{return _selectedIndex }; 
     set{_selectedIndex=value;OnPropertyChanged("SelectedIndex") }; 
     }

这样,当selectedindex更改时,将通知列表

“对不起,如果有任何拼写错误,我直接在这里写了这个,而不是在代码编辑器中,所以你可能会得到错别字”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM