我正在尝试从视图模型中设置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";
}
}
}
答案 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);
}
}