首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更新控件属性会破坏OneWay绑定吗?

更新控件属性会破坏OneWay绑定吗?
EN

Stack Overflow用户
提问于 2018-08-15 06:49:15
回答 1查看 62关注 0票数 0

考虑下面这个非常简单的例子,其中我有一个UserControl,如下所示:

UserControl XAML:

代码语言:javascript
复制
<UserControl x:Class="BindingTest.SomeControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Name="SomeControlElement">
    <Grid>
        <TextBlock Text="{Binding ElementName=SomeControlElement, Path=Counter}" />
    </Grid>
</UserControl>

代码背后:

代码语言:javascript
复制
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace BindingTest
{ 
    public partial class SomeControl : UserControl
    {
        public SomeControl()
        {
            InitializeComponent();

            var timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 5);
            timer.Tick += (s, e) => Counter = Counter + 1;
            timer.Start();
        }

        public int Counter
        {
            get { return (int)GetValue(CounterProperty); }
            set { SetValue(CounterProperty, value); }
        }
        public static readonly DependencyProperty CounterProperty = DependencyProperty.Register(nameof(Counter), typeof(int), typeof(SomeControl), new PropertyMetadata(0));
    }
}

所以这个控件只显示一个TextBlock,每5秒增加一个计数器。当然,我还有一个消费者:

MainWindow XAML:

代码语言:javascript
复制
<Window x:Class="BindingTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BindingTest"
        x:Name="MainWindowName" Width="200" Height="300">
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <StackPanel>
            <local:SomeControl Counter="{Binding ElementName=MainWindowName, Path=SomeSource, Mode=OneWay}" />
            <local:SomeControl Counter="{Binding ElementName=MainWindowName, Path=SomeSource, Mode=TwoWay}" />
        </StackPanel>
    </Grid>
</Window>

最后,背后的主要守则是:

代码语言:javascript
复制
using System;
using System.Windows;
using System.ComponentModel;
using System.Windows.Threading;
namespace BindingTest
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public MainWindow()
        {
            InitializeComponent();
            var timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(0, 0, 1);
            timer.Tick += (s, e) => SomeSource = SomeSource + 1;
            timer.Start();
        }

        private int someSource;
        public int SomeSource
        {
            get => someSource;
            set
            {
                if (someSource != value)
                {
                    someSource = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SomeSource)));
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

对,所以主程序后面有一个计数器,每秒钟更新一个属性。XAML有两个UserControl实例。一个具有OneWay绑定,另一个具有TwoWay绑定。

我在这里看到的是,当"SomeControl.cs“中的计数器更新时,第一个UserControl (OneWay)的绑定就中断了。有TwoWay的那个一直在更新。

这是出于设计(以及为什么)?更重要的是,如果我需要更新UserControls中的属性,那么如何在我的示例中做到这一点-以支持OneWay绑定?请注意,在本例中,我对TwoWay绑定并不感兴趣,因为它将更新"MySource“,这是而不是我想要的!

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-15 08:45:49

这是精心设计的。当将所谓的局部值分配给依赖属性时,将替换以前分配的OneWay绑定。TwoWay绑定保持活动状态,并更新其源属性。

然而,有一个解决办法。不要设置本地值,而是设置“当前值”。替换

代码语言:javascript
复制
timer.Tick += (s, e) => Counter = Counter + 1;

使用

代码语言:javascript
复制
timer.Tick += (s, e) => SetCurrentValue(CounterProperty, Counter + 1);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51854137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档