WPF数据绑定与ViewModel作为属性

时间:2018-07-25 07:00:37

标签: c# wpf xaml mvvm data-binding

为了保持MainWindow.xaml.cs的清洁,我尝试将所有内容外包给ViewModel类,然后将视图绑定到ViewModel属性的属性
但是,使用此额外的层似乎无效。我的列表和文本框保持空白。有什么办法可以使这种方法起作用?

MainWindow类:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public ViewModel ViewModel { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        ViewModel = new ViewModel();
    }
}

ViewModel类:

public class ViewModel : INotifyPropertyChanged
{
    private string m_oneLineOnly;

    private ObservableCollection<string> m_sampleLines;

    public ObservableCollection<string> SampleLines
    {
        get => m_sampleLines;
        set
        {
            m_sampleLines = value;
            RaisePropertyChanged(nameof(SampleLines));
        }
    }

    public string OneLineOnly
    {
        get => m_oneLineOnly;

        set
        {
            m_oneLineOnly = value;
            RaisePropertyChanged(nameof(OneLineOnly));
        }
    }

    public ViewModel()
    {
        SampleLines = new ObservableCollection<string>(new List<string>()
        {
            "Gedanken",
            "Zeit",
            "Sand"
        });

        OneLineOnly = "Hello World";
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    private void RaisePropertyChanged(string propertyName)
    {
        var handlers = PropertyChanged;

        handlers(this, new PropertyChangedEventArgs(propertyName));
    }
}

MainWindow XAML

<Window x:Class="DataContext_Test_Project.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:DataContext_Test_Project"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800"
    x:Name="Window">
<Grid>
    <ListBox 
        HorizontalAlignment="Left"
        Height="100"
        Margin="334,132,0,0"
        VerticalAlignment="Top"
        Width="100"
        ItemsSource="{Binding ElementName=Window, Path=ViewModel.SampleLines}"/>
    <TextBox
        HorizontalAlignment="Left" 
        Height="23"
        Margin="184,166,0,0" 
        TextWrapping="Wrap"
        VerticalAlignment="Top"
        Width="120"
        DataContext="{Binding ElementName=Window, Path=ViewModel}"
        Text="{Binding Path=OneLineOnly}"/>
</Grid>

3 个答案:

答案 0 :(得分:2)

您还可以在后面的代码中定义DataContext:

public partial class MainWindow : Window
{
    public ViewModel ViewModel { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        ViewModel = new ViewModel();
        DataContext = ViewModel;
    }
}

并清理您的XAML:

<Grid>
    <ListBox 
         HorizontalAlignment="Left"
         Height="100"
         Margin="334,132,0,0"
         VerticalAlignment="Top"
         Width="100"
         ItemsSource="{Binding SampleLines}"/>
    <TextBox
         HorizontalAlignment="Left" 
         Height="23"
         Margin="184,166,0,0" 
         TextWrapping="Wrap"
         VerticalAlignment="Top"
         Width="120"
         Text="{Binding OneLineOnly}"/>
</Grid>

答案 1 :(得分:1)

为了使绑定像

ItemsSource="{Binding ElementName=Window, Path=ViewModel.SampleLines}"
DataContext="{Binding ElementName=Window, Path=ViewModel}"

工作,您有两个选择。使ViewModel属性触发属性更改通知,或者只是在解析XAML之前即在调用InitializeComponent()之前对其进行初始化:

赞:

public partial class MainWindow : Window
{
    public ViewModel ViewModel { get; }

    public MainWindow()
    {     
        ViewModel = new ViewModel();
        InitializeComponent();
    }
}

或更简单:

public partial class MainWindow : Window
{
    public ViewModel ViewModel { get; } = new ViewModel();

    public MainWindow()
    {     
        InitializeComponent();
    }
}

答案 2 :(得分:0)

从xaml.cs文件中删除以下行:ViewModel = new ViewModel(); 对Xaml文件使用以下代码:

<Window x:Class="DataContext_Test_Project.MainWindow"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                    xmlns:local="clr-namespace:DataContext_Test_Project"
                    mc:Ignorable="d"
                    Title="MainWindow" Height="450" Width="800"
                    x:Name="Window" DataContext="{DynamicResource ViewModel}">
     <Window.Resources>
            <local:ViewModel x:Key="ViewModel"/>
            </Window.Resources>
                <Grid>
                    <ListBox 
                        HorizontalAlignment="Left"
                        Height="100"
                        Margin="334,132,0,0"
                        VerticalAlignment="Top"
                        Width="100"
                        ItemsSource="{Binding Path=SampleLines}"/>
                    <TextBox
                        HorizontalAlignment="Left" 
                        Height="23"
                        Margin="184,166,0,0" 
                        TextWrapping="Wrap"
                        VerticalAlignment="Top"
                        Width="120"
                        Text="{Binding Path=OneLineOnly}"/>
                </Grid>
        </Window>