无法从viewmodel在usercontrol中设置属性

时间:2012-09-25 12:45:32

标签: c# wpf user-controls mvvm-light dependency-properties

我正在尝试从视图模型中设置usercontrol中的属性,该控件旨在捕获并显示用户签名。 我在从视图模型中设置usercontrol中的属性时遇到问题。 从usercontrol接收签名到视图模型可以正常工作。

如何解决这个问题的任何想法都将非常感激。

我的测试代码如下。

用户控制XAML:

 <UserControl x:Class="mvvmSignature.ucSignature"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="212" d:DesignWidth="300" Background="#FFEFFCEF">
    <Grid Height="210">
        <InkCanvas MinHeight="73" HorizontalAlignment="Left" Margin="10,27,0,0" Name="inkCanvas1" VerticalAlignment="Top" MinWidth="278" LostMouseCapture="inkCanvas1_LostMouseCapture" />
        <Button Content="Clear" Height="23" HorizontalAlignment="Left" Margin="33,142,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="buttonClear_Click" />
        <Button Content="Load on user control" Height="23" Margin="143,143,36,45" Click="ButtonLoad_Click" />
    </Grid>
</UserControl>

UserControl CodeBehind:

using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
namespace mvvmSignature
{
    public partial class ucSignature : UserControl
    {
        public ucSignature()
        {
            InitializeComponent();
        }
        private void inkCanvas1_LostMouseCapture(object sender, MouseEventArgs e)
        {
            SetSignature();
        }
        private void SetSignature()
        {
            var sb = new StringBuilder();
            using (var ms = new MemoryStream())
            {
                inkCanvas1.Strokes.Save(ms);
                foreach (var item in ms.ToArray())
                {
                    sb.AppendFormat("{0},",
                                        item);
                }
                ms.Close();
            }
            var local = sb.ToString().Trim() + "¬¬¬";
            local = local.Replace(",¬¬¬", string.Empty);
            Signature = local;
        }
        private void LoadSignature(string signatureIn)
        {
            if (string.IsNullOrEmpty(signatureIn) || !signatureIn.Contains(",")) return;
            var x = signatureIn.Split(',').Select(byte.Parse).ToArray();
            if (!x.Any()) return;
            using (var ms = new MemoryStream(x))
            {
                inkCanvas1.Strokes = new StrokeCollection(ms);
                ms.Close();
            }
        }
        public static DependencyProperty SignatureProperty =
        DependencyProperty.Register("Signature", typeof(string),
                                    typeof(ucSignature));
        public string Signature
        {
            get { return (string) GetValue(SignatureProperty); }
            set
            {
                SetValue(SignatureProperty, value);
                LoadSignature(value);
            }
        }
        private void ButtonLoad_Click(object sender, RoutedEventArgs e)
        {
            Signature = "0,136,3,3,6,72,16,69,53,70,53,17,0,0,128,63,31,9,17,0,0,0,0,0,0,240,63,10,237,2,186,1,135,240,12,39,128,97,109,28,4,156,51,90,235,138,135,131,227,95,107,253,119,193,35,104,195,186,246,103,1,195,179,59,78,134,195,179,92,167,188,180,76,206,211,192,77,175,108,211,28,53,136,32,51,41,156,210,3,148,109,22,188,163,105,195,188,11,92,11,184,122,101,188,166,182,124,53,106,153,90,44,217,71,15,64,102,115,59,52,205,105,1,53,128,76,166,179,73,156,202,107,0,195,248,122,106,153,64,22,185,164,210,3,51,154,64,102,51,8,5,174,105,52,128,204,102,19,57,156,215,41,90,69,162,103,1,128,76,128,19,40,4,6,1,102,153,205,96,22,105,156,206,101,53,180,89,230,83,88,4,202,107,0,179,38,120,122,215,52,195,248,120,179,101,25,158,80,195,179,41,156,210,107,50,180,205,38,144,25,156,214,105,52,153,97,249,165,166,101,52,180,205,32,48,0,135,231,164,231,113,153,131,40,225,168,4,6,1,1,128,89,160,22,105,164,214,207,135,32,56,110,3,52,153,192,96,19,80,0,11,68,6,1,105,11,76,2,215,135,50,142,28,77,48,253,160,180,225,232,12,2,107,52,128,205,38,115,91,68,214,105,51,153,77,112,238,30,77,102,80,9,148,214,1,1,154,76,230,64,38,80,8,12,2,101,50,180,205,11,70,29,128,225,236,63,0,153,77,96,19,9,141,154,207,102,153,204,230,19,24,12,209,105,154,64,96,19,89,148,204,0,76,166,118,121,132,204,77,38,179,56,13,170,3,51,128,64,109,24,126,104,154,32,54,121,148,202,103,52,153,77,96,9,144";
        }
        private void buttonClear_Click(object sender, RoutedEventArgs e)
        {
            inkCanvas1.Strokes.Clear();
            SetSignature();
        }
    }
}

MainWindow XAML:

<Window xmlns:my="clr-namespace:mvvmSignature"  x:Class="mvvmSignature.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:ignore="http://www.ignore.com"
    mc:Ignorable="d ignore"
    Height="490"
    Width="327"        
    DataContext="{Binding Main, Source={StaticResource Locator}}">   
<StackPanel>
    <my:ucSignature  Signature ="{Binding Signature,Mode=TwoWay}"  />
    <Button Width ="140" Height ="30" Content ="Load On Main Page" Command="{Binding LoadOnMainPageCommand}" />
    <TextBox FontSize="8"
               Foreground="Purple"
               Text="{Binding Signature,Mode=TwoWay}"
               VerticalAlignment="Center"
               HorizontalAlignment="Center"
               TextWrapping="Wrap" Height="210" />
</StackPanel>

MainViewModel:

using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
namespace mvvmSignature.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        public ICommand LoadOnMainPageCommand { get; set; }
        public const string WelcomeTitlePropertyName = "Signature";
        private string _signature = string.Empty;
        public string Signature 
        {
            get
            {
                return _signature;
            }
            set
            {
                if (_signature == value)
                {
                    return;
                }
                _signature = value;
                RaisePropertyChanged(WelcomeTitlePropertyName);
            }
        }

        public MainViewModel()
        {
            LoadOnMainPageCommand = new RelayCommand(LoadSignature);
        }

        private void LoadSignature()
        {
            Signature ="0,136,3,3,6,72,16,69,53,70,53,17,0,0,128,63,31,9,17,0,0,0,0,0,0,240,63,10,237,2,186,1,135,240,12,39,128,97,109,28,4,156,51,90,235,138,135,131,227,95,107,253,119,193,35,104,195,186,246,103,1,195,179,59,78,134,195,179,92,167,188,180,76,206,211,192,77,175,108,211,28,53,136,32,51,41,156,210,3,148,109,22,188,163,105,195,188,11,92,11,184,122,101,188,166,182,124,53,106,153,90,44,217,71,15,64,102,115,59,52,205,105,1,53,128,76,166,179,73,156,202,107,0,195,248,122,106,153,64,22,185,164,210,3,51,154,64,102,51,8,5,174,105,52,128,204,102,19,57,156,215,41,90,69,162,103,1,128,76,128,19,40,4,6,1,102,153,205,96,22,105,156,206,101,53,180,89,230,83,88,4,202,107,0,179,38,120,122,215,52,195,248,120,179,101,25,158,80,195,179,41,156,210,107,50,180,205,38,144,25,156,214,105,52,153,97,249,165,166,101,52,180,205,32,48,0,135,231,164,231,113,153,131,40,225,168,4,6,1,1,128,89,160,22,105,164,214,207,135,32,56,110,3,52,153,192,96,19,80,0,11,68,6,1,105,11,76,2,215,135,50,142,28,77,48,253,160,180,225,232,12,2,107,52,128,205,38,115,91,68,214,105,51,153,77,112,238,30,77,102,80,9,148,214,1,1,154,76,230,64,38,80,8,12,2,101,50,180,205,11,70,29,128,225,236,63,0,153,77,96,19,9,141,154,207,102,153,204,230,19,24,12,209,105,154,64,96,19,89,148,204,0,76,166,118,121,132,204,77,38,179,56,13,170,3,51,128,64,109,24,126,104,154,32,54,121,148,202,103,52,153,77,96,9,144";
        }
    }
}

3 个答案:

答案 0 :(得分:1)

我重新编写了部分ucSignature类,以正确声明并使用代码中的Signature属性。请改用此类定义,让我知道它是否更好。

public partial class ucSignature : UserControl
{
    public ucSignature()
    {
        InitializeComponent();
    }

    private void inkCanvas1_LostMouseCapture(object sender, MouseEventArgs e)
    {
        var sb = new StringBuilder();
        using (var ms = new MemoryStream())
        {
            inkCanvas1.Strokes.Save(ms);
            foreach (var item in ms.ToArray())
            {
                sb.AppendFormat("{0},", item);
            }
            ms.Close();
        }
        var local = sb.ToString().Trim() + "¬¬¬";
        local = local.Replace(",¬¬¬", string.Empty);

        this.SetValue(SignatureProperty, local);
    }

    private void LoadSignature(string signatureIn)
    {
        if (string.IsNullOrEmpty(signatureIn) || !signatureIn.Contains(",")) return;
        var x = signatureIn.Split(',').Select(byte.Parse).ToArray();
        if (!x.Any()) return;
        using (var ms = new MemoryStream(x))
        {
            inkCanvas1.Strokes = new StrokeCollection(ms);
            ms.Close();
        }
    }

    public static DependencyProperty SignatureProperty = DependencyProperty.Register(
        "Signature",
        typeof(string),
        typeof(ucSignature),
        new UIPropertyMetadata(OnSignaturePropertyChanged));

    public static string GetSignature(ucSignature signature)
    {
        return (string)signature.GetValue(SignatureProperty);
    }

    public static void SetSignature(ucSignature signature, string value)
    {
        signature.SetValue(SignatureProperty, value);
    }

    private static void OnSignaturePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        var signature = obj as ucSignature;

        if (signature != null)
        {
            LoadSignature(args.NewValue.ToString());
        }
    }

    private void ButtonLoad_Click(object sender, RoutedEventArgs e)
    {
        this.SetValue(SignatureProperty, "0,136,3,3,6,72,16,69,53,70,53,17,0,0,128,63,31,9,17,0,0,0,0,0,0,240,63,10,237,2,186,1,135,240,12,39,128,97,109,28,4,156,51,90,235,138,135,131,227,95,107,253,119,193,35,104,195,186,246,103,1,195,179,59,78,134,195,179,92,167,188,180,76,206,211,192,77,175,108,211,28,53,136,32,51,41,156,210,3,148,109,22,188,163,105,195,188,11,92,11,184,122,101,188,166,182,124,53,106,153,90,44,217,71,15,64,102,115,59,52,205,105,1,53,128,76,166,179,73,156,202,107,0,195,248,122,106,153,64,22,185,164,210,3,51,154,64,102,51,8,5,174,105,52,128,204,102,19,57,156,215,41,90,69,162,103,1,128,76,128,19,40,4,6,1,102,153,205,96,22,105,156,206,101,53,180,89,230,83,88,4,202,107,0,179,38,120,122,215,52,195,248,120,179,101,25,158,80,195,179,41,156,210,107,50,180,205,38,144,25,156,214,105,52,153,97,249,165,166,101,52,180,205,32,48,0,135,231,164,231,113,153,131,40,225,168,4,6,1,1,128,89,160,22,105,164,214,207,135,32,56,110,3,52,153,192,96,19,80,0,11,68,6,1,105,11,76,2,215,135,50,142,28,77,48,253,160,180,225,232,12,2,107,52,128,205,38,115,91,68,214,105,51,153,77,112,238,30,77,102,80,9,148,214,1,1,154,76,230,64,38,80,8,12,2,101,50,180,205,11,70,29,128,225,236,63,0,153,77,96,19,9,141,154,207,102,153,204,230,19,24,12,209,105,154,64,96,19,89,148,204,0,76,166,118,121,132,204,77,38,179,56,13,170,3,51,128,64,109,24,126,104,154,32,54,121,148,202,103,52,153,77,96,9,144");
    }
    private void buttonClear_Click(object sender, RoutedEventArgs e)
    {
        inkCanvas1.Strokes.Clear();
        this.SetValue(SignatureProperty, string.Empty);
    }
}

答案 1 :(得分:0)

您需要将MainViewModel设置为MainWindow的DataContext,以便绑定有效。除非你在构造函数中设置它,否则我看不到它被设置在任何地方。你可以尝试这样的事情:

<Application.Resources>         
<local:MainViewModel x:Key="MainViewModel" />     
</Application.Resources>

DataContext="{StaticResource MainViewModel}" 

答案 2 :(得分:0)

我将假设它是您尝试设置的Signature属性,主要是因为这是您的用户控件的全部内容,而这就是我看到问题的地方。

设置Signature属性后,在另一个属性上调用RaisePropertyChanged:WelcomeTitlePropertyName属性。你应该在你设置的同一个属性上调用RaisePropertyChanged,否则你的UI(即你的用户控件)将不知道它。

例如,在您的MainWindow XAML中,您放置了一个ucSignature元素,如下所示:

<my:ucSignature Signature ="{Binding Signature,Mode=TwoWay}"  />

那部分没问题,但在你的ViewModel中,应该像这样定义属性:

private string _signature = string.Empty;
public string Signature 
    {
        get { return _signature; }
        set
        {
            if (_signature == value)
                return;

            _signature = value;
            RaisePropertyChanged(Signature);
        }
    }