【问题标题】:My MVVM pattern is not working... Why?我的 MVVM 模式不起作用……为什么?
【发布时间】:2016-08-05 23:43:42
【问题描述】:

在这个例子中,我尝试开发一个简单的工具来为客户管理软件许可证。它在 C# WPF 中实现,中心设计模式基于 MVVM 范式(使用 INotifyPropertyChanged、ICommand 和其他东西分离表示层和逻辑/数据层)。

为什么不能在 XAML 中动态绑定属性? 请查看末尾的附加链接以获取更多信息。

感谢您的帮助!

菲利克斯

我的观点的相关部分(XAML):

<DataGrid ItemsScource="{Binding Licenses}" SelectedItem="{Binding SelectedLicense}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding CustomerConverted}" Header="Customer"/>
                <DataGridTextColumn Binding="{Binding LicenseNoConverted}" Header="License no."/>
                <DataGridTextColumn Binding="{Binding LicenseKey}" Header="License key"/>
                <DataGridTextColumn Binding="{Binding LastActivation}" Header="Last activated ver."/>
                <DataGridTextColumn Binding="{Binding TypeConverted}"/>
            </DataGrid.Columns>
        </DataGrid> 

代码隐藏

public partial class WMain : Window {
    public WMain() { 
        InitializeComponent();

        //construct ViewModel (works fine, all properties are consistent)
        WMainCtrl ctrl = new WMainCtrl(); 

        //set data context in code behind (XAML-bindings are not working)
        this.DataContext = ctrl;

        //that works instead... why?
        //c_dgLicenses.ItemsSource = ctrl.Licenses;        
    }
}

视图模型:

public class WMainCtrl : BaseCtrl {

    public WMainCtrl() {
        try {
            //init data
            License.selectAndConvertData();
        } catch (Exception exc) {
            throw exc;
        }
    }

    //this works, the collection is definitely filled 
    internal ObservableCollection<License> Licenses { get { return License.Obscol; } }

    private License _selectedLicense;
    public License SelectedLicense {
        get {
            if (_selectedLicense == null) {
                if (Licenses.Count == 0) {
                    return null;
                }
                return Licenses[0];
            } else
            return _selectedLicense;
        }
        set {
            if (_selectedLicense != value) {
                _selectedLicense = value;
                try {
                    Console.WriteLine(SelectedLicense.LicenseKey);
                } catch (Exception) {}
                OnPropertyChanged();
            }
        }
    }
}

ViewModelBase 的相关部分:

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null) {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

以下是一些详细信息:

Architecture (rough draft, no UML rules)

Screenshot: DataContext is set properly?!

【问题讨论】:

  • 不确定是否相关,但网格不应该有ItemsSource="{Binding Licenses}" 而不是DataContext="{Binding Licenses}"
  • 如果不自己重新创建项目,很难说......尝试将您的 ObservableCollection 许可证更改为公共(来自内部)
  • @DmitryRotay 您应该将其发布为答案
  • 我都试过了。它没有用......但是谢谢,我会在我的例子中调整它。
  • @Monty 谢谢!现在一切正常......我以为我要疯了。正如您再次看到的那样,四只眼睛比两只眼睛好。我没有考虑修饰符...:D

标签: c# xaml mvvm binding datacontext


【解决方案1】:

您在 DataGrid 上输入错误的 ItemsSource:

DataGrid ItemsScource="{Binding Licenses}" SelectedItem="{Binding SelectedLicense}"

【讨论】:

  • 是的,我知道。最初它是“ItemsSource = ...”。 "DataContext=..." 只是一个测试。但它现在有效。问题是我的 ViewModel 中的修饰符“internal ObservableCollection”。现在解决了!
【解决方案2】:

我的旧 ViewModel 属性(不工作)

internal ObservableCollection<License> Licenses { get { return License.Obscol; } }

我的新 ViewModel 属性(工作)

public ObservableCollection<License> Licenses { get { return License.Obscol; } }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 2020-09-30
    相关资源
    最近更新 更多