使用MVVM在WPF中与ItemSource绑定/DataContext问题 [英] Binding/DataContext Issue with ItemSource in WPF using MVVM

查看:104
本文介绍了使用MVVM在WPF中与ItemSource绑定/DataContext问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ViewModel,它是一个Window,在此Window中,有很多我创建的UserControl.这些可以正常工作,并且分别设置每个的绑定和DataContext;除了一个...

I have a ViewModel that is a Window, inside this Window there are many UserControls that I have made. These work fine and the bindings and DataContexts for each is set appropriately; all apart from one...

在我的MainWindowView XAML中,我有

In my MainWindowView XAML I have

<Controls:LogViewerView HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        DataContext="{Binding LogViewerViewModel}"/>

在我的MainWindowViewModel中,我有

public LogViewerViewModel LogViewerViewModel { get; set; }

LogViewerView

<UserControl x:Class="GambitFramework.Utilities.Controls.Views.LogViewerView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:Caliburn="http://www.caliburnproject.org"
             xmlns:Models="clr-namespace:GambitFramework.Utilities.Models"
             mc:Ignorable="d" 
             d:DesignHeight="300" 
             d:DesignWidth="200">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="../../Resources/Styles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>   
    </UserControl.Resources>
    <DockPanel>
        <ItemsControl ItemsSource="{Binding LogEntries}" 
                          Style="{StaticResource LogViewerStyle}">
            <ItemsControl.Template>
                <ControlTemplate>
                    <ScrollViewer CanContentScroll="True">
                        <ItemsPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </ItemsControl.Template>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel IsItemsHost="True"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </DockPanel>
</UserControl>

其中LogViewerViewModel

public class LogViewerViewModel : PropertyChangedBase
{
    private BindableCollection<LogEntry> logEntries;

    public LogViewerViewModel() { }
    public LogViewerViewModel(IEnumerable<LogEntry> logEntries)
    {
        LogEntries = new BindableCollection<LogEntry>(logEntries);
    }

    public BindableCollection<LogEntry> LogEntries
    {
        get { return logEntries; }
        set
        {
            logEntries = value;
            NotifyOfPropertyChange(() => LogEntries);
        }
    }
}

以及在Styles.xaml中的何处

and where in Styles.xaml we have

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:Caliburn="http://www.caliburnproject.org" 
                    xmlns:Models="clr-namespace:GambitFramework.Utilities.Models">
    <Style x:Key="LogViewerStyle" TargetType="ItemsControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ScrollViewer CanContentScroll="True">
                        <ItemsPresenter/>
                    </ScrollViewer>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel IsItemsHost="True"/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <DataTemplate DataType="{x:Type Models:LogEntry}">
        <Grid IsSharedSizeScope="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition SharedSizeGroup="Timestamp" Width="Auto"/>
                <ColumnDefinition SharedSizeGroup="Index" Width="Auto"/>
                <ColumnDefinition SharedSizeGroup="IconSource" Width="Auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Timestamp}" 
                       Grid.Column="0"
                       FontWeight="Bold" 
                       Margin="5,0,5,0"/>
            <TextBlock Text="{Binding Index}" 
                       Grid.Column="1"
                       FontWeight="Bold" 
                       Margin="0,0,2,0" />
            <TextBlock Text="{Binding Message}" 
                       Grid.Column="3"
                       TextWrapping="Wrap"/>
        </Grid>
    </DataTemplate>
</ResourceDictionary>

LogEntry的模型在哪里

public class LogEntry : PropertyChangedBase
{
    private uint index;
    private DateTime timestamp;
    private IconPresentor iconSource;
    private string message;

    public uint Index
    {
        get { return index; }
        set
        {
            index = value;
            NotifyOfPropertyChange(() => Index);
        }
    }

    public DateTime Timestamp
    {
        get { return timestamp; }
        set
        {
            timestamp = value;
            NotifyOfPropertyChange(() => Timestamp);
        }
    }

    public string Message
    {
        get { return message; }
        set
        {
            message = value;
            NotifyOfPropertyChange(() => Message);
        }
    }
}

但是我的物品没有显示,当我使用Snoop检查绑定时

But my items are not being displayed and when I use Snoop to check the bindings

无法设置表达式.它被标记为不可共享",并且已被使用

Cannot set Expression. It is marked as 'NonShareable' and has already been used

明确表明DataContext设置不正确.我在这里做错什么,为什么我的DataContext没有设置为我的控件?

which clearly suggests the DataContext is not set correctly. What am I doing wrong here and why is my DataContext not set for my control?

非常感谢您的时间.

编辑.这是使用相同日志控件但绑定到背后代码的答案,我想绑定到单独的文件: https ://stackoverflow.com/a/16745054/626442

推荐答案

您正在将LogViewerViewModel绑定到MainWindowView的DataContext而不是LogViewerView的DataContext

You are binding the LogViewerViewModel to the DataContext of the MainWindowView instead of the DataContext of the LogViewerView

如果要从父级的DataContext派生,请查看类似的问题,例如:

If you want to derive from parent's DataContext, have a look at similar questions like: How to access parent's DataContext from a UserControl

请注意,DataTemplate有点特殊: https://stackoverflow.com/a/4480488

Notice that the DataTemplate is a bit special: https://stackoverflow.com/a/4480488

这篇关于使用MVVM在WPF中与ItemSource绑定/DataContext问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆