【问题标题】:Using Calburn.Micro with the Extended WPF Toolkit?将 Calburn.Micro 与扩展的 WPF 工具包一起使用?
【发布时间】:2013-06-25 19:26:43
【问题描述】:

我正在使用扩展 WPF 工具包中的 IntegerUpDown 控件,并且我也在使用 Caliburn.Micro 和 PostSharp。我试图让它根据我的 ViewModel 中的属性设置控件的最大值和最小值。

我可以让最小值或最大值起作用,但不能同时使用。所以我显然在做一些只允许最后一个属性绑定的事情。这是我的AppBootstrapper 课程:

using Caliburn.Micro;
using System.Windows;
using Xceed.Wpf.Toolkit;

namespace Test {
    public class AppBootstrapper : Bootstrapper<MainViewModel>{

        static AppBootstrapper() {
            var baseBindProperties = ViewModelBinder.BindProperties;

            ConventionManager.AddElementConvention<FrameworkElement>(IntegerUpDown.MinimumProperty, "Minimum", "ValueChanged");
            ViewModelBinder.BindProperties =
                (frameWorkElements, viewModels) => {
                    foreach (var frameworkElement in frameWorkElements) {
                        var propertyName = frameworkElement.Name + "Minimum";
                        var property = viewModels
                                .GetPropertyCaseInsensitive(propertyName);
                        if (property != null) {
                            var convention = ConventionManager
                                .GetElementConvention(typeof(FrameworkElement));
                            ConventionManager.SetBindingWithoutBindingOverwrite(
                                viewModels,
                                propertyName,
                                property,
                                frameworkElement,
                                convention,
                                convention.GetBindableProperty(frameworkElement));
                        }
                    }
                    return baseBindProperties(frameWorkElements, viewModels);
                };

            ConventionManager.AddElementConvention<FrameworkElement>(IntegerUpDown.MaximumProperty, "Maximum", "ValueChanged");
            ViewModelBinder.BindProperties =
                (frameWorkElements, viewModels) => {
                    foreach (var frameworkElement in frameWorkElements) {
                        var propertyName = frameworkElement.Name + "Maximum";
                        var property = viewModels
                                .GetPropertyCaseInsensitive(propertyName);
                        if (property != null) {
                            var convention = ConventionManager
                                .GetElementConvention(typeof(FrameworkElement));
                            ConventionManager.SetBindingWithoutBindingOverwrite(
                                viewModels,
                                propertyName,
                                property,
                                frameworkElement,
                                convention,
                                convention.GetBindableProperty(frameworkElement));
                        }
                    }
                    return baseBindProperties(frameWorkElements, viewModels);
                };
        }
    }
}

在上面的示例中,设置了最大值,但没有设置最小值。如果我交换它们,以便最后设置最小绑定,则最小值有效,但最大值无效。我在这里做错了什么?

为了完整起见,如果你想运行它,这里是 MainView.xaml:

<Window x:Class="Test.MainView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox Name="Text"/>
        <xctk:IntegerUpDown Name="Number"/>
        <Button Name="Click" Height="25" Content="Test"/>
    </StackPanel>
</Window>

和 MainViewModel.cs:

using Caliburn.Micro;
using PostSharp.Patterns.Model;
using System;

namespace Test {

    [NotifyPropertyChanged]
    public class MainViewModel : Screen {

        public string Text { get; set; }

        public int Number { get; set; }

        public int NumberMaximum { get; set; }

        public int NumberMinimum { get; set; }

        public MainViewModel()
            : base() {
            this.NumberMinimum = 50;
            this.NumberMaximum = 100;
            this.Number = 75;
        }

        public void Click() {
            Console.WriteLine("Text: '"+this.Text+"'");
            Console.WriteLine("Number: '"+this.Number+"'");
        }

        protected void OnPropertyChanged(string propertyName) {
            NotifyOfPropertyChange(propertyName);
        }
    }
}

【问题讨论】:

    标签: c# wpf wpftoolkit caliburn.micro


    【解决方案1】:

    我发现是这样的

    ConventionManager.GetElementConvention(typeof(FrameworkElement));
    

    并没有真正返回正确的约定,而是总是返回最后添加的约定。我还认为我在静态构造函数中将它们设置在错误的位置。所以我把它移到了一个覆盖的Configure 方法中。我的AppBootstrapper 类现在看起来像:

    using Caliburn.Micro;
    using System.Windows;
    using Xceed.Wpf.Toolkit;
    
    namespace Test {
        public class AppBootstrapper : Bootstrapper<MainViewModel>{
    
            protected override void Configure() {
                base.Configure();
    
                //setup the conventions
                var valueConvention = ConventionManager.AddElementConvention<FrameworkElement>(IntegerUpDown.ValueProperty, "Value", "ValueChanged");
                var maximumConvention = ConventionManager.AddElementConvention<FrameworkElement>(IntegerUpDown.MaximumProperty, "Maximum", "ValueChanged");
                var minimumConvention = ConventionManager.AddElementConvention<FrameworkElement>(IntegerUpDown.MinimumProperty, "Minimum", "ValueChanged");
    
                //bind the properties
                var baseBindProperties = ViewModelBinder.BindProperties;
                ViewModelBinder.BindProperties =
                    (frameWorkElements, viewModels) => {
    
                        foreach (var frameworkElement in frameWorkElements) {
                            var valuePropertyName = frameworkElement.Name;
                            var valueProperty = viewModels
                                    .GetPropertyCaseInsensitive(valuePropertyName);
    
                            if (valueProperty != null) {
                                ConventionManager.SetBindingWithoutBindingOverwrite(
                                        viewModels,
                                        valuePropertyName,
                                        valueProperty,
                                        frameworkElement,
                                        valueConvention,
                                        valueConvention.GetBindableProperty(frameworkElement));
                            }
    
                            var maxPropertyName = frameworkElement.Name + "Maximum";
                            var maxProperty = viewModels
                                    .GetPropertyCaseInsensitive(maxPropertyName);
    
                            if (maxProperty != null) {
                                ConventionManager.SetBindingWithoutBindingOverwrite(
                                        viewModels,
                                        maxPropertyName,
                                        maxProperty,
                                        frameworkElement,
                                        maximumConvention,
                                        maximumConvention.GetBindableProperty(frameworkElement));
                            }
    
                            var minPropertyName = frameworkElement.Name + "Minimum";
                            var minProperty = viewModels
                                    .GetPropertyCaseInsensitive(minPropertyName);
    
                            if (minProperty != null) {
                                ConventionManager.SetBindingWithoutBindingOverwrite(
                                    viewModels,
                                    minPropertyName,
                                    minProperty,
                                    frameworkElement,
                                    minimumConvention,
                                    minimumConvention.GetBindableProperty(frameworkElement));
                            }
                        }
    
                        return baseBindProperties(frameWorkElements, viewModels);
                    };
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      • 1970-01-01
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      相关资源
      最近更新 更多