簡體   English   中英

有關用戶控件中DependencyProperty設置程序中代碼的問題

[英]Questions about codes in the setter of a DependencyProperty in a user control

我正在頁面上作為用戶控件( ClockControl )顯示時間/時鍾,實際時間模型是由另一個類( ClockTime )的DateTime對象驅動的。 我在ClockControl上有2個文本塊:

  1. 文本塊“ Second_update_by_binding”綁定到依賴項屬性“ Second_binded”,后者又綁定到模型ClockTime“ Second”。

  2. 通過操縱模型ClockTime'Second'的值來更新文本塊'Second_update_by_manipulating',以便如果'Second'僅是1位數(或小於10),則在其前面添加'0'。

我設法達到了我想要的目標,而不管它是最好的方法。 但是,我遇到了一些我不太理解為什么會發生的問題。 特別是,我最困惑的是Clock用戶控件中的dependency屬性中的getter / setter內的代碼背后的邏輯。

MainPage.xaml中:

<Page x:Class="App1.MainPage" ...">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <local:ClockControl x:Name="useControl" 
               Second_binded="{Binding Second}" 
               Second_manipulated="{Binding Second}"  />
    </Grid>
</Page>

MainPage.cs:

public sealed partial class MainPage : Page
{
    ClockTime clock;
    DispatcherTimer Timer;

    public MainPage()
    {
        clock = new ClockTime();
        this.InitializeComponent();
        this.DataContext = clock;
          // I am adding this DispatchTimer to force the update of the text 
          // 'Second_update_by_manipulating' on the ClockControl since the
          // Binding of Second_manipulated doesnt work
        Timer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 1) };
        Timer.Tick += Timer_Tick;
        Timer.Start();
    }

    private void Timer_Tick(object sender, object e)
    {
        useControl.Second_manipulated = clock.Second.ToString();
    }
}

ClockTime模型:

class ClockTime : INotifyPropertyChanged
{
    public ClockTime()
    {
        var Timer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 1) };
        Timer.Tick += Timer_Tick;
        Timer.Start();
    }

    private void Timer_Tick(object sender, object e)
    {
        Second = DateTime.Now.Second;
    }

    //===================================================
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
    //===================================================
    private int _second;
    public int Second
    {
        get { return this._second; }
        set
        {
            if (value != this._second)
            {
                this._second = value;
                NotifyPropertyChanged("Second");
            }
        }
    }
}

ClockControl.xaml:

<UserControl x:Class="App1.ClockControl" ...>
    <Grid>
        <StackPanel>
            <TextBlock x:Name="Second_update_by_manipulating"  />
            <TextBlock x:Name="Second_update_by_binding" Text="{Binding Second_binded}" />
        </StackPanel>
    </Grid>
</UserControl>

ClockControl.cs:

public sealed partial class ClockControl : UserControl
{
    public ClockControl()
    {
        this.InitializeComponent();
        (this.Content as FrameworkElement).DataContext = this;
    }
    //==================================
    public String Second_binded
    {
        get {
            return (String)GetValue(Second_bindedProperty); 
        }
        set {
            Debug.WriteLine(" in Second_binded ");
            SetValue(Second_bindedProperty, value);
        }
    }
    public static readonly DependencyProperty Second_bindedProperty =
        DependencyProperty.Register(
        "Second_binded", 
        typeof(string),
        typeof(ClockControl), 
        new PropertyMetadata(""));
    //==================================
    public String Second_manipulated
    {
        get
        {
            return (String)GetValue(Second_manipulatedProperty);
        }
        set
        {
            Second_update_by_manipulating.Text = (Convert.ToInt32(value)<10) ? "0"+value : value;
            Debug.WriteLine(" in Second_manipulated ");
            SetValue(Second_manipulatedProperty, value);
        }
    }
    public static readonly DependencyProperty Second_manipulatedProperty =
        DependencyProperty.Register(
        "Second_manipulated",
        typeof(string),
        typeof(ClockControl),
        new PropertyMetadata(""));
    //==================================
}

所以這是我的問題:

  1. 為什么調試代碼Debug.WriteLine(“在Second_binded”)中; 在更新ClockTime模型中的“ Second”時,永遠不會調用ClockControl中Second_binded依賴項屬性的setter中的值。

  2. 代碼Debug.WriteLine(“ Second_manipulated”)中的代碼 在ClockControl中的Second_manipulated依賴項屬性的setter中調用,代碼Value_1.Text =(Convert.ToInt32(value)<10)? “ 0” +值:值; 執行此命令以更改ClockControl上的文本,但僅在添加另一個與MainPage.cs一起使用的DispatchTimer以強制代碼useControl.Second_manipulated = clock.Second.ToString();之后,此方法才起作用 更新時間。 即使我已經在MainPage.xaml中將Second_manipulated綁定到Second,為什么我仍必須以這種方式來更新Second_manipulated?

任何能啟發我對C#知識的想法和評論都非常歡迎。

謝謝

如果要跟蹤DependencyProperty更改,則必須注冊一個PropertyChangedCallback處理程序。 綁定的值更新時,系統不會觸發屬性設置器。

public static readonly DependencyProperty Second_bindedProperty =
        DependencyProperty.Register(
        "Second_binded",
        typeof(string),
        typeof(ClockControl),
        new PropertyMetadata("", PropertyChangedCallback));

private static void PropertyChangedCallback(DependencyObject dependencyObject,
             DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
    Debug.WriteLine(" in Second_binded callback");
}

之所以會在第二個屬性中找到您的二傳手,是因為您使用useControl.Second_manipulated = clock.Second.ToString();強制自己進行useControl.Second_manipulated = clock.Second.ToString(); ,這不是使用綁定的正確方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM