2011-09-15 66 views
-1
势必

我创建了像数字UPDOWN用户控制如下用户控件的依赖项属性没有得到在Silverlight

<StackPanel Orientation="Horizontal" VerticalAlignment="Top" > 
    <TextBox x:Name="InputTextBox" Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" 
       Style="{StaticResource NumericUpDownTextBoxStyle}" 

      KeyDown="InputTextBox_KeyDown" 
      KeyUp="InputTextBox_KeyUp" 
      GotFocus="InputTextBox_GotFocus" 
      LostFocus="InputTextBox_LostFocus" 
      MouseWheel="InputTextBox_MouseWheel" 
      MouseEnter="InputTextBox_MouseEnter" 
      LayoutUpdated="InputTextBox_LayoutUpdated" 
      Text="{Binding Path=ControlValue, Mode=TwoWay,ValidatesOnDataErrors=True,ValidatesOnExceptions=True,NotifyOnValidationError=True}"/> 
</StackPanel> 

我已经绑定一个ViewModel这种控制,我设置ControlValue属性的文本框属性用户控件模板文本框。

Everthing在控制级别上正常工作。我已经从usercontrol公开。

public static readonly DependencyProperty MaximumValueProperty; 

public static readonly DependencyProperty MinimumValueProperty; 

public static readonly DependencyProperty StepValueProperty; 

public static readonly DependencyProperty TextValueProperty; 

我的属性是

财产
public double Maximum 
{ 
    get 
    { 
     return (double)GetValue(MaximumValueProperty); 
    } 
    set 
    { 
     SetValue(MaximumValueProperty, value); 
     this.ViewModel.Maximum = this.Maximum; 
    } 
} 

public double Minimum 
{ 
    get 
    { 
     return (double)GetValue(MinimumValueProperty); 
    } 
    set 
    { 
     SetValue(MinimumValueProperty, value); 
     this.ViewModel.Minimum = this.Minimum; 
    } 
} 

public double Step 
{ 
    get 
    { 
     return (double)GetValue(StepValueProperty); 
    } 
    set 
    { 
     SetValue(StepValueProperty, value); 
     this.ViewModel.Step = this.Step; 
    } 
} 

public double TextValue 
{ 
    get 
    { 
     return (double)GetValue(TextValueProperty); 
    } 
    set 
    { 
     SetValue(TextValueProperty, value); 
     this.ViewModel.ControlValue = Convert.ToString(value); 
    } 
} 

初始化。

static NumericUpDown() 
    { 
     MaximumValueProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(NumericUpDown), new PropertyMetadata(null)); 
     MinimumValueProperty = DependencyProperty.Register("Minimum", typeof(double), typeof(NumericUpDown), new PropertyMetadata(null)); 
     StepValueProperty = DependencyProperty.Register("Step", typeof(double), typeof(NumericUpDown), new PropertyMetadata(null)); 
     TextValueProperty = DependencyProperty.Register("TextValue", typeof(double), typeof(NumericUpDown), new PropertyMetadata(null)); 
    } 

我在MainPage.xaml页面用户控件执行如下命令

<local:NumericUpDown Maximum="28" Minimum="-28" Step="0.25" TextValue="{Binding ElementName=FranePrice, Path=DataContext.FranePrice}"></local:NumericUpDown> 

在那里我有另一种视图模型,我绑定到XAML页面并没有在我绑定视图模型一个属性到UserControl的TextValue属性。

FramePrice是在视图模型的属性,我绑定到用户控制

和主页XAML的TextValue属性

<UserControl x:Class="DatePicker.MainPage" 
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:local="clr-namespace:DatePicker" 
mc:Ignorable="d" 
d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> 

<Grid x:Name="LayoutRoot" Background="White"> 
    <StackPanel Orientation="Vertical"> 

     <local:NumericUpDown Maximum="28" Minimum="-28" Step="0.25" TextValue="{Binding ElementName=FranePrice, Path=DataContext.FranePrice}"></local:NumericUpDown> 
     <Button Content="Show Date" Height="23" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click"/> 
    </StackPanel> 
</Grid> 

此视图页面模型我在哪里使用用户控件。在单击事件我向用户显示TextValue。

公共类MainPageViewModel:EntityViewModel {

public MainPageViewModel() 
    { 

    } 
    private double framePrice; 
    public Double FramePrice 
    { 
     get 
     { 
      return framePrice; 
     } 
     set 
     { 
      framePrice = value; 
      PropertyChangedHandler("FramePrice"); 
     } 
    } 
} 

当我改变TextValue在用户控制其在页面视图模型的FramePrice财产亘古不变的变化。

代码中有任何错误。

卢克伍德沃德的文章中,我如下

public static readonly DependencyProperty MaximumValueProperty; 
    public static readonly DependencyProperty MinimumValueProperty; 
    public static readonly DependencyProperty StepValueProperty; 
    public static readonly DependencyProperty TextValueProperty; 

    public static double Max; 
    public static double Min; 
    public static double Stp; 
    public static double Val; 

    public double Maximum 
    { 
     get 
     { 
      return (double)GetValue(MaximumValueProperty); 
     } 
     set 
     { 
      SetValue(MaximumValueProperty, value); 
     } 
    } 

    public double Minimum 
    { 
     get 
     { 
      return (double)GetValue(MinimumValueProperty); 
     } 
     set 
     { 
      SetValue(MinimumValueProperty, value); 
     } 
    } 

    public double Step 
    { 
     get 
     { 
      return (double)GetValue(StepValueProperty); 
     } 
     set 
     { 
      SetValue(StepValueProperty, value); 
     } 
    } 

    public double TextValue 
    { 
     get 
     { 
      return (double)GetValue(TextValueProperty); 
     } 
     set 
     { 
      SetValue(TextValueProperty, value); 
     } 
    } 
    static NumericUpDown() 
    { 
     MaximumValueProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(NumericUpDown), new PropertyMetadata(new PropertyChangedCallback(onMaximumValueChanged))); 
     MinimumValueProperty = DependencyProperty.Register("Minimum", typeof(double), typeof(NumericUpDown), new PropertyMetadata(new PropertyChangedCallback(onMinimumValueChanged))); 
     StepValueProperty = DependencyProperty.Register("Step", typeof(double), typeof(NumericUpDown), new PropertyMetadata(new PropertyChangedCallback(onStepValueChanged))); 
     TextValueProperty = DependencyProperty.Register("TextValue", typeof(double), typeof(NumericUpDown), new PropertyMetadata(new PropertyChangedCallback(onTextValueChanged))); 
    } 

    private static void onStepValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     Stp = (double)e.NewValue; 
    } 
    private static void onMinimumValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     Min = (double)e.NewValue; 
    } 
    private static void onMaximumValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     Max = (double)e.NewValue; 
    } 
    private static void onTextValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     Val = (double)e.NewValue; 
    } 

然后我访问最大值,最小值,STP和Val财产在用户控件的视图模型来执行我的逻辑已更新的代码。

和XAML代码是如下

<local:NumericUpDown x:Name="ctlUpDown" Maximum="28" Minimum="-28" Step="0.25" TextValue="{Binding Path=FramePrice}"></local:NumericUpDown> 

用户控制

<StackPanel Margin="5" Orientation="Horizontal" VerticalAlignment="Center"> 
    <TextBox x:Name="InputTextBox" Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" 
      Height="23" VerticalAlignment="Top" 
      Width="50" TextAlignment="Center" 
      KeyDown="InputTextBox_KeyDown" 
      KeyUp="InputTextBox_KeyUp" 
      GotFocus="InputTextBox_GotFocus" 
      LostFocus="InputTextBox_LostFocus" 
      MouseWheel="InputTextBox_MouseWheel" 
      MouseEnter="InputTextBox_MouseEnter" 
      Text="{Binding Path=TextValue, ElementName=ctlUpDown, Mode=TwoWay,ValidatesOnDataErrors=True,ValidatesOnExceptions=True,NotifyOnValidationError=True}" 
      /> 
</StackPanel> 
+0

您的依赖项属性不完整(例如,没有注册属性的初学者),并且您不显示FramePrice代码。请更新您的问题与缺少的项目。 –

+0

我做了**没有**告诉你添加那些静态变量'Min','Max','Stp'和'Val'。他们不会做你想做的事情,因为他们是“静态”的,因此可以在所有的Nu​​mericUpDown控件中共享。他们是不正确的,你应该摆脱他们。你也把'x:Name =“ctlUpDown”'放在错误的地方。您的NumericUpDown.xaml文件应该以''元素开始,并且'x:Name'进入该元素,而不是在<元素。 –

+0

@Luke WoodWard我尝试了很多,但没有解决它。我已经创建了一个相同的应用程序,你可以通过它使它可行? http://www.4shared.com/folder/KhfV9l-9/_online.html这里是链接。 –

回答

1

我发现错了你的代码是的第一件事性质MaximumMinimumStepTextValue。这里的TextValue性质:由依赖项属性支持

public double TextValue 
{ 
    get 
    { 
     return (double)GetValue(TextValueProperty); 
    } 
    set 
    { 
     SetValue(TextValueProperty, value); 
     this.ViewModel.ControlValue = Convert.ToString(value); 
    } 
} 

属性,如我上面提到的四个,应该ALWAYS如下所示:

public double TextValue 
{ 
    get { return (double)GetValue(TextValueProperty); } 
    set { SetValue(TextValueProperty, value); } 
} 

在换句话说, getter应该只包含对GetValue的调用,而setter应该只包含对SetValue的调用。

原因是当Silverlight更改TextValue依赖项属性的值时,它不会通过使用上面的属性来完成此操作。依赖项属性的值存储在Silverlight依赖关系系统中,当Silverlight想要更改其中一个属性的值时,它将直接转到此依赖关系系统。它根本不叫你的代码。像上面这样的属性仅仅是为了您的方便而提供的,为您提供了一种访问和更改存储在依赖项属性中的值的简单方法。除了你自己的代码之外,它们绝不会被其他任何东西所调用

一般情况下,如果要在一个依赖属性值发生变化,则需要注册依赖属性时,必须通过PropertyChangedCallback在PropertyMetadata被称为一个方法。不过,我怀疑你的情况你不需要那样做。

在我看来,你有三个属性:

  • 在您的视图模型类FramePrice财产,
  • 您的NumericUpDown用户控件的TextValue依赖属性,
  • 文本依赖属性您的NumericUpDown用户控件的XAML中的TextBox。

我的印象是,您希望您的视图模型中的FramePrice属性始终具有与TextBox的Text属性相同的值。为此,需要将FramePrice属性绑定到NumericUpDown的TextValue属性,然后将其绑定到TextBox的Text属性。

要将这两个属性的前两个绑定在一起,需要更改几件事情。首先,在你的<local:NumericUpDown>元素TextValue属性应该像

TextValue="{Binding Path=FramePrice}" 

结合{Binding ElementName=FramePrice, Path=DataContext.FramePrice}将无法​​正常工作,因为在你的XAML没有元素与属性x:Name="FramePrice"{Binding ...}中的ElementName属性的值必须与XAML中对象的x:Name匹配。

您还需要为您的主页设置DataContext。如果您的主页视图模型对象具有零参数构造函数,则执行此操作的一种方法是遵循this answer

到第二两个属性结合在一起,我想:

  • x:Name属性添加到您的NumericUpDown控件的<UserControl>元素(x:Name="ctlUpDown",说),
  • 更换TextBoxText财产在您的NumericUpDown控件中使用以下内容:

    Text="{Binding Path=TextValue, ElementName=ctlUpDown, Mode=TwoWay, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, NotifyOnValidationError=True}"/> 
    

完成之后,您可以删除代码隐藏课程中的所有行this.ViewModel.SomeProperty = ...。他们没有必要,正如我已经解释过的,他们不会在你想要的时候运行。

最后,有没有理由不使用Silverlight Toolkit的NumericUpDown控件?

编辑2:根据我的判断,我查看了您上传的两个Silverlight项目之一(我忽略了其中有_2的项目)。它与你的问题有很小的相似之处。

我只能假设你想要两个文本框(其中一个在用户控件中)始终具有相同的值。我能够做以下修改后,要做到这一点:

  • MainPageViewModel.cs:添加ClearErrorFromProperty("DPropertyBind");到属性的setter。 (否则,验证错误永远不会被清除。)

  • MyUserControlWVM.xaml:去除参考LostFocus事件处理程序,在Text属性添加绑定,并添加x:Name属性添加到<UserControl>元素。换句话说,现在看起来如下:

    <UserControl x:Class="DependencyPropertyBinding.MyUserControlWVM" 
        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" 
        mc:Ignorable="d" 
        x:Name="ctlWVM" 
        d:DesignHeight="300" d:DesignWidth="205"> 
        <StackPanel Orientation="Horizontal" Width="204" Height="32"> 
         <TextBox x:Name="textbox" Height="30" Width="200" Text="{Binding Path=DProperty, ElementName=ctlWVM, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" /> 
        </StackPanel> 
    </UserControl> 
    
  • MyUserControlWVM.xaml.cs:重命名的依赖属性DependencyPropertyValueDPropertyProperty(命名约定是static readonly领域具有属性的名称(在这种情况下, DProperty),附加Property)。我还删除了TextBox_LostFocus事件处理程序。

+0

伍德沃德非常感谢指导。我在我的应用程序中发现了一些Tab键问题,我使用了近15个NumericUpdown控件。根据你的上述我更改了代码从Setter和Getter中删除了所有的代码,并且在你解释的XAML中完成了绑定,但是我的FramePrice仍然没有通过用户控制得到改变。 –

+0

感谢您的回答我做了改变,其工作正常。现在的问题是,当我在用户控件中输入任何内容时,我应该在用户控件上得到验证通知。在没有输入任何内容的情况下,我在主页面的文本框中获取验证通知,因为其属性与用户控件属性绑定。为什么我不会得到相同的通知? –

+0

现在工作。 –

0

的XAML和如果上述代码是准确你在结合

拼写 FramePriceFranePrice

当页面loa时,输出窗口应该显示为绑定错误DED。

它是目前 Binding ElementName=FranePrice, Path=DataContext.FranePrice

应该是: Binding ElementName=FramePrice, Path=DataContext.FramePrice

“有了很大的结合能力越大,责任越大” :)

+0

我纠正了拼写,但m仍然在绑定问题。 –

+0

@HiTech:代码中有太多不一致和错误,我认为你现在会在这里一会儿;) – AnthonyWJones

+0

看看ViewModel被属性直接引用的方式,你不是在开玩笑。可能会运行一个工作版本只是为了它:) –

相关问题