wpf - 如何使用不在代码隐藏中的 XAML 绑定(bind) ListView ItemsSou

我遵循 MVVM 模式,我想使用 XAML 绑定(bind) ListView ItemsSource,甚至不绑定(bind) 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 内部的菜单属性

        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 绑定(bind)到我的主窗口的 DataContext 和 Path=ViewModel 的 MainMenu,因此 MainMain 是 ViewModel 的对象,我可以在其中将此属性绑定(bind)到 ListView 的 ItemsSource,但它不起作用。

不对的地方请指正。

最佳答案

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

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

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

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

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

关于wpf - 如何使用不在代码隐藏中的 XAML 绑定(bind) ListView ItemsSource。?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8103033/

相关文章:

wpf - 从 DataTemplate 中的控件获取 GridViewColumn

.net - 有没有人使用 DbEnumerator

iphone - 使用场景转换动画化 UIKit 项目

ruby-on-rails-3 - 无法修改关联,因为源反射类通过 :has_many + rail

html-agility-pack - html 敏捷包和文本中的三角括号

sql-server - 'Insert into linked table failed, RAI

continuous-integration - 自动构建 Access 2007 数据库

macos - Mac 上的实时动态壁纸(桌面)

drupal - 在 drupal 7 中将表单元素添加到节点以供用户输入

Ruby Gem 安装失败 - 执行 gem 时出错 - 未初始化的常量 Syck::Syck