2011-09-15 58 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被屬性直接引用的方式,你不是在開玩笑。可能會運行一個工作版本只是爲了它:) –

相關問題