【问题标题】:Master Detail MVVM WPF not working主细节 MVVM WPF 不工作
【发布时间】:2009-10-14 12:55:28
【问题描述】:

我无法让我的绑定在 Detail ListView 上工作。我在下面粘贴了我所有的 MVVM 模式代码。请帮忙!!!

我的观点: DirectoryDe​​tailView.cs

<UserControl x:Class="S2.Views.DirectoryDetailView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <ListView Grid.Column="0" ItemsSource="{Binding Path = DirectoryDetails}"
              IsSynchronizedWithCurrentItem="True"
              SelectedItem="{Binding SelectedDirName, Mode=TwoWay}">
        <ListView.View>
            <GridView>
                <GridViewColumn DisplayMemberBinding="{Binding Path = FileName}"
                                Header="File Name"/>
            </GridView>
        </ListView.View>
    </ListView>
    <ListView Grid.Column="1" Margin="10,0,0,0" ItemsSource="{Binding Path = DirectoryDetails}">
        <ListView.View>
            <GridView>
                <GridViewColumn DisplayMemberBinding="{Binding Path = FileDetails.Length}"
                                Header="Length"/>
                <GridViewColumn DisplayMemberBinding="{Binding Path = FileDetails.LastAccessTime}"
                                Header="LastAccessTime"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

我的模特:

public class DirectoryModel : INotifyPropertyChanged
{
    private string _fileName;
    private DateTime _createdTime;

    public string FileName
    {
        get
        {
            return _fileName;
        }
        set
        {
            _fileName = value;
            RaisePropertyChanged("FileName");
        }
    }

    private IEnumerable<FileDetails> _fileDetails;

    public IEnumerable<FileDetails> FileDetails
    {
        get
        {
            return _fileDetails;
        }
        set
        {
            _fileDetails = value;
            RaisePropertyChanged("FileDetails");
        }

    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    protected void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler propertyChanged = PropertyChanged;

        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public class FileDetails
{
    public long Length { get; set; }

    public DateTime LastAccessTime { get; set; }
}

我的视图模型:

public class DirectoryViewModel : BaseViewModel
{
    private IEnumerable<DirectoryModel> _directoryDetails;

    public IEnumerable<DirectoryModel> DirectoryDetails
    {
        get
        {
            var service = GetService<IDirectoryService>();
            _directoryDetails = service.GetDirectoryDetails();
            return _directoryDetails;
        }
        set
        {
            if(_directoryDetails != value)
            {
                _directoryDetails = value;
                base.RaisePropertyChanged("DirectoryDetails");
            }
        }
    }

    private DirectoryModel _selectedDirName;

    public DirectoryModel SelectedDirName
    {
        get
        {
            return _selectedDirName;
        }
        set
        {
            _selectedDirName = value;
            base.RaisePropertyChanged("SelectedDirName");
        }
    }
}

请告诉我,我做错了什么?

谢谢, AG

【问题讨论】:

  • 你的问题到底是什么?
  • 您忘记粘贴可能包含您遇到问题的绑定的 XAML?
  • 我已经粘贴了我的 Xaml 代码,但它没有出现在板上。不知道为什么?。我尝试多次编辑帖子仍然无法显示 Xaml。你知道可能是什么问题吗?
  • 这个问题与 XML 括号有关(我认为)......可能是 SO 代码中的一个错误......我今天也遇到了 XML 代码的问题
  • 我现在已经设法让我的 xaml 显示出来,想知道是否有人可以提供帮助

标签: c# wpf data-binding mvvm


【解决方案1】:

我不记得我是从哪里得到这种技术的,但它在用于调试绑定时非常有用

在项目中添加一个名为 Debugconverter 的类

public class DebugConverter : IValueConverter {
  public object Convert(object value,
     Type targetType, object parameter,
     System.Globalization.CultureInfo culture) {

     return value; //set the breakpoint here
  }

  public object ConvertBack(object value,
   Type targetType,
   object parameter,
   System.Globalization.CultureInfo culture) {

     return value;
  }

}

然后我在 app.xaml 中添加对它的引用

     <currentProjectNamespace:DebugConverter
        x:Key="debugConverter" />

然后在绑定中使用它,

Binding="{Binding Path=PropertyName, Converter={StaticResource debugConverter}}"

当绑定发生时,你会遇到断点,没有它我会被搞砸的。还要检查输出窗口,那里有绑定失败的列表。

【讨论】:

  • 好主意。我将需要做一些大量数据绑定的控件,而这(调试数据绑定)是我不知道如何解决的问题之一。
  • 我一直用来调试绑定的技巧之一是设置“Path=。”在我的绑定中查看它试图绑定的对象,通常不是您期望的对象。
【解决方案2】:

没有看到 XAML 很难说,但我的第一个想法是 1)您尚未将 DataContext 属性设置为 ViewModel 或 2)您在 Binding 本身中存在一些语法问题。

您应该使用 ObservableCollection 而不是 IEnumerable 来支持 DataBinding。我也不确定您的 DirectoryDe​​tails getter 的实施是否有益。您的 setter 直接设置私有变量并触发 PropertyChanged 事件 - 这是正确的。但是您的 getter 也直接设置变量,绕过 PropertyChanged 事件。更不用说你有一个 getter 做一个 setter 的工作,这在几个层面上可能是个坏主意。我认为你最好简化你的吸气剂并让它返回私有变量。您真的需要每次都检索详细信息还是可以使用局部变量?

我还要指出,你不需要在你的模型上实现 INotifyPropertyChanged:ViewModel 需要这个接口来支持 DataBinding,但是将它添加到 Model 类中并没有真正的价值。

【讨论】:

  • 我不知道你是否还需要帮助,但正如我上面提到的,我看不到你在哪里设置了DataContext。您的 DirectoryViewModel 对象需要定义为 DataSource,然后在某处实例化和引用:添加对您的命名空间的引用:xmlns:YourNamespace="clr-namespace:YourNamespace;assembly=YourAssembly" 在您的资源中: 然后将数据源添加为您的 DataContext:
  • 抱歉 - DataContext 应该是这样的:DataContext="{Binding Source={StaticResource myDataSource}}"
【解决方案3】:

知道问题出在哪里会很有帮助...不过,我要问的问题是:-

你的吸气剂是否被击中(在其中设置断点)?

第一个列表视图有效,第二个无效?

如果只有第二个失败,我猜问题是您尝试将两列绑定到属性 IEnumerable FileDetails,然后您尝试遵循 IEnumerable 上的属性路径,这不会工作,因为它是一组对象,而不是一个。您是否从上面的列表视图中复制并粘贴了您的代码,并且没有正确设置项目来源?

运行时输出窗口中有什么?它通常会告诉您找不到绑定路径。如果您遵循上面的调试转换器建议,您可以找出您要绑定的内容(如果有的话)

【讨论】:

    猜你喜欢
    • 2018-06-19
    • 2011-01-02
    • 2016-08-16
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多