【问题标题】:How to Bind ListView ItemsSource using XAML not in Code behind.?如何使用不在代码后面的 XAML 绑定 ListView ItemsSource。?
【发布时间】:2011-12-27 12:44:36
【问题描述】:

我正在关注 MVVM 模式,我想使用 XAML 绑定 ListView ItemsSource,甚至没有 this.Datacontext = ObservableCollection 属性。

我的代码是这样的:

            <ListView x:Name="MenuBarList" 
                  Grid.Row="2"
                  ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
                  ItemsSource="{Binding Path=Menu.Option}"
                  Width="{Binding MainMenuWidth}"
                  SelectedItem="{Binding Path=SelectedMainMenuOption, Mode=TwoWay}" >
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>

            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Title}" TextWrapping="Wrap" IsHitTestVisible="False" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

Menu 是属性,它将位于 ViewModel 上。 Option 是属性的类,所以我使用的是 Menu.Option

My Menu 是 ContentMenuModel 类型的属性,ContentMenuModel 是包含 Option 和 Title 和 Image 属性的类。

查看 ViewModel 内的 Menu 属性

        public const string MenuPropertyName = "Menu";

    private ContentMenuModel _Menu = null;

    /// <summary>
    /// Gets the Menu collection.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>
    public ContentMenuModel Menu
    {
        get
        {
            return _Menu;
        }

        set
        {
            if (_Menu == value)
                return;

            _Menu = value;

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

ContentMenuModel 类看起来像这样:

    public class ContentMenuModel 
{

    #region Title

    /// <summary>
    /// The <see cref="Title" /> property's name.
    /// </summary>
    public const string TitlePropertyName = "Title";

    private string _Title = String.Empty;

    /// <summary>
    /// Gets the Title property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>

    [Required]
    [StringLength(128, ErrorMessage = "The Title value cannot exceed 128 characters. ")]
    public string Title
    {
        get
        {
            return _Title;
        }

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

            var oldValue = _Title;
            _Title = value;

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

    #endregion

    #region Options

    /// <summary>
    /// The <see cref="Options" /> property's name.
    /// </summary>
    public const string OptionsPropertyName = "Options";

    private ObservableCollection<ContentMenuOptionModel> _Options = null;

    /// <summary>
    /// Gets the Options property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>

    public ObservableCollection<ContentMenuOptionModel> Options
    {
        get
        {
            return _Options;
        }

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

            var oldValue = _Options;
            _Options = value;

            RaisePropertyChanged(OptionsPropertyName);
        }
    }

    #endregion

    #region ContextText

    /// <summary>
    /// The <see cref="Options" /> property's name.
    /// </summary>
    public const string ContextTextPropertyName = "ContextText";

    private ContentPageItem _ContextText = null;

    /// <summary>
    /// Gets the ContextText property.
    /// Changes to that property's value raise the PropertyChanged event. 
    /// </summary>

    public ContentPageItem ContextText
    {
        get
        {
            return _ContextText;
        }

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

            _ContextText = value;

            RaisePropertyChanged(OptionsPropertyName);
        }
    }

    #endregion
}

我已将 ViewModelLocator 绑定到我的主窗口的 DataContext 和 Path=ViewModel 的 MainMenu,因此 MainMain 是 ViewModel 的对象,我可以在其中将此属性绑定到 ListView 的 ItemsSource,但它不起作用。

请纠正我的错误。

【问题讨论】:

    标签: wpf listview binding mvvm-light


    【解决方案1】:

    为了快速获得完整示例,您可以安装 NUGet for Visual Studio 并通过它在干净的 WPF 应用程序项目上安装 MVVMLight 包。然后它将设置所有内容,您将看到它是如何工作的。 虽然我将在这里描述基础知识。 MVVMLight 开箱即用地支持这一点。 MVVMligth 的标准模板包括ViewModelLocatorMainViewModelViewModelLocator - 是包含所有其他视图模型的类。从一开始它只有一个属性public MainViewModel Main {get;}ViewModelLocator 在 App.xaml 中注册为资源

    <Application>
      <Application.Resources>
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
      </Application.Resources>
    </Application>
    

    然后,在任何页面上,如果您想访问视图模型,您应该简单地引用 Locator 资源并获取适合您页面的属性。这是MainWindow 及其MainViewModel 的示例:

    <Window DataContext="{Binding Source={StaticResource Locator}, Path=Main}">
        <Grid>
            <TextBlock Text="{Binding Text}"/>
        </Grid>
    </Window>
    

    在上面的示例中,我已将public string Text {get;} 属性添加到MainViewModel 并引用。在示例中,不需要任何代码隐藏,一切都是通过 xaml 以声明方式设置的。

    【讨论】:

    • 嗨弗拉迪姆我有同样的你解释我,但它没有给我想要的结果,因为我更早之前有 RadCarousel Control,它运行良好,但列表视图不起作用。
    • 显示您的 Option 类和 Menu 类,它们的外观。
    • 我正在修改我的代码,请查看并纠正我。谢谢。
    【解决方案2】:

    只需添加 ListView 的 Grid 并将 DataContext 分配给源,它就会工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-08
      • 2012-03-30
      • 2012-10-14
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 2019-03-07
      • 1970-01-01
      相关资源
      最近更新 更多