首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于数据绑定计算的延迟触发器

用于数据绑定计算的延迟触发器
EN

Stack Overflow用户
提问于 2018-12-08 21:33:25
回答 1查看 70关注 0票数 0

我对WPF非常陌生,目前正在学习数据绑定的概念。

我简化的XAML代码。除了我的问题(以下),它工作良好-快速和肮脏放置对象通过GUI,将清理一旦工作:

代码语言:javascript
复制
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="60"/>
            <RowDefinition/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
        </Grid>
        <Grid Grid.Row="1">
            <GroupBox Header="Change Type:" Height="95" Width="100" VerticalAlignment="Top" Margin="270,4,422,0" >
                <StackPanel>
                    <RadioButton x:Name="RbtAdd" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Top" GroupName="modGroup" Checked="ModeRadio_Checked">
                        <WrapPanel>
                            <TextBlock Text="Add" Foreground="Green"/>
                        </WrapPanel>
                    </RadioButton>
                    <RadioButton x:Name="RbtPull" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Top" GroupName="modGroup" Checked="ModeRadio_Checked">
                        <WrapPanel>
                            <TextBlock Text="Pull" Foreground="Blue"/>
                        </WrapPanel>
                    </RadioButton>
                    <RadioButton x:Name="RbtModify" HorizontalAlignment="Left" Margin="5" VerticalAlignment="Top" GroupName="modGroup" Checked="ModeRadio_Checked">
                        <WrapPanel>
                            <TextBlock Text="Modify" Foreground="DarkGray"/>
                        </WrapPanel>
                    </RadioButton>
                </StackPanel>
            </GroupBox>

            <TextBlock x:Name="txtCurStock" HorizontalAlignment="Left" Margin="330,181,0,0" TextWrapping="Wrap" Text="{Binding Path=CurrentStock}" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" TextAlignment="Center"/>

            <Label Content="Current stock:" HorizontalAlignment="Left" Margin="289,156,0,0" VerticalAlignment="Top"/>
            <Label x:Name ="lblOperation" Content="Stock to Pull:" HorizontalAlignment="Left" Margin="507,156,0,0" VerticalAlignment="Top"/>
            <TextBox x:Name="txtEntry" HorizontalAlignment="Left" Height="32" Margin="489,181,0,0" TextWrapping="Wrap" TextAlignment="Center" Text="{Binding Path=ModEntry}" VerticalAlignment="Top" Width="120" FontSize="20" FontWeight="Bold" TextChanged="TxtEntry_TextChanged"/>
            <Label Content="New Stock" HorizontalAlignment="Right" Margin="714,156,0,0" VerticalAlignment="Top" Width="68"/>
            <TextBlock Text="{Binding Path=NewStock}" HorizontalAlignment="Right" Margin="0,186,10,0" TextAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" Width="68"/>
            <TextBox x:Name="txtComment"  HorizontalAlignment="Left" Height="86" Margin="289,233,0,0" TextWrapping="Wrap" Text="{Binding Path=ModEntry}" VerticalAlignment="Top" Width="493"/>
            <Label Content="Comment:" HorizontalAlignment="Left" Margin="289,207,0,0" VerticalAlignment="Top"/>

            <TextBlock x:Name ="txtModindicator" HorizontalAlignment="Left" Margin="433,181,0,0" TextWrapping="Wrap" Text="-" FontSize="20" FontWeight="Bold" VerticalAlignment="Top"/>
            <TextBlock x:Name ="txtResindicator" HorizontalAlignment="Left" Margin="663,182,0,0" TextWrapping="Wrap" Text="=" FontSize="20" FontWeight="Bold" VerticalAlignment="Top"/>

        </Grid>
    </Grid>

现在是缩短的c#代码:

代码语言:javascript
复制
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Runtime.CompilerServices;


namespace SomeWPF
{
    /// <summary>
    /// Interaction logic for ModifyWindow.xaml
    /// </summary>
    public partial class MainWindow : INotifyPropertyChanged
    {

        public enum Mymode
        {
            add,
            pull,
            modify
        }

        public Mymode mode;

        public MainWindow()
        {
            DataContext = this;
            InitializeComponent();

            CurrentStock = 5;
            RbtPull.IsChecked = true;
            ModEntry = 1;

        }

        private void ModeRadio_Checked(object sender, RoutedEventArgs e)
        {
            if (sender != null)
            {
                if (sender.Equals(RbtAdd))
                {
                    mode = Mymode.add;
                    txtModindicator.Text = "+";
                    txtComment.Text = "Add";
                    lblOperation.Content = "Stock to Add:";
                }
                else if (sender.Equals(RbtPull))
                {
                    mode = Mymode.pull;
                    txtModindicator.Text = "-";
                    txtComment.Text = "Pull";
                    lblOperation.Content = "Stock to Pull:";
                }
                else
                {
                    mode = Mymode.modify;
                    txtModindicator.Text = "~";
                    lblOperation.Content = "Corrected Quantity:";
                    txtComment.Text = "Mod";
                }
                TxtEntry_TextChanged(sender, null);
            }
        }

        private void TxtEntry_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (mode == Mymode.add)
            {
                NewStock = CurrentStock + ModEntry;
            }
            else if (mode == Mymode.pull)
            {
                NewStock = CurrentStock - ModEntry;
            }
            else
            {
                NewStock = ModEntry;
            }

        }

        #region Binding Stuff

        private int _newstock;
        public int NewStock
        {

            get
            {

                return _newstock;
            }
            set
            {

                if (_newstock != value)
                {
                    _newstock = value;
                    OnPropertyChanged();
                }
            }
        }

        private int _modentry;
        public int ModEntry
        {
            get
            {
                return _modentry;
            }
            set
            {
                if (_modentry != value)
                {
                    _modentry = value;
                    OnPropertyChanged();
                }
            }
        }

        private int _currentstock;
        public int CurrentStock
        {
            get
            {
                return _currentstock;
            }
            set
            {
                if (_currentstock != value)
                {
                    _currentstock = value;
                    OnPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion


    }
}

因此,这个窗口是一个弹出式的小程序中的库存存储,供用户输入库存的移动。到目前为止,一切都很好,我现在想做一个非常简单的计算部分。使用“旧”winforms c#,您只需获取值并“手动”更新结果的文本属性,当然,我们(I)希望学习新的内容,并使用数据绑定进行操作。代码也做了计算,但触发器不知何故不是我想要的。

假设当前库存为5当窗口加载,模式被设置为拉(RbtPull)和用户条目(绑定到ModEntry)被设置为1通过代码。因此,NewStock应该是正确显示的4。(是的)注释字段(目前用于调试)显示ModEntry值1。

现在我在股票中输入3来拉动字段,但是什么都没有发生。(我希望它能“实时”反应)。new仍然显示为4,注释仍然显示为1。当我离开字段(然后单击注释字段)--检测到属性更改,注释字段也显示3 (=ModEntry) --所以它不是“实时”,而是仅在字段失去焦点时触发,但这也是可以接受的。

真正的问题是:新股票保持4,不计算。现在,当我再次进入Stock以拉出字段并将值更改为5时,New字段将更新为2(因此,对于我在5-3=2之前输入的值),用再次5覆盖该字段将更改为0。所以总是“落后一步”。

根据我的发现,我有一个想法,我需要某种绑定转换器,而不是我的计算方法,但我真的找不到合适的东西,而且对数据绑定还不够熟悉。已经在绑定变量代码中直接尝试了一些东西,但是都没有工作。如果有人能告诉我正确的方向,我会非常感激的。(不需要银板解决方案,而只是知道如何搜索(例如,如果我使用的绑定方式是有意义的,或者我需要添加一些东西等等)。

非常感谢!

PS:当然,如果有人主动给出银盘解决方案,我也会很感激。)--对英语不好,没有母语的人感到抱歉。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-10 08:14:28

@nosale的第二个链接(见注释)提供了问题的答案。将XAML字段txtEntry和UpdateSourceTrigger=PropertyChanged结果字段设置为UpdateSourceTrigger=PropertyChanged解决了这个问题。

因此,正确的块现在看起来是这样的,不需要更改c#代码:

代码语言:javascript
复制
    <Label Content="Current stock:" HorizontalAlignment="Left" Margin="289,156,0,0" VerticalAlignment="Top"/>
    <Label x:Name ="lblOperation" Content="Stock to Pull:" HorizontalAlignment="Left" Margin="507,156,0,0" VerticalAlignment="Top"/>
    <TextBox x:Name="txtEntry" HorizontalAlignment="Left" Height="32" Margin="489,181,0,0" TextWrapping="Wrap" TextAlignment="Center" Text="{Binding Path=ModEntry, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Width="120" FontSize="20" FontWeight="Bold" TextChanged="TxtEntry_TextChanged"/>
    <Label Content="New Stock" HorizontalAlignment="Right" Margin="714,156,0,0" VerticalAlignment="Top" Width="68"/>
    <TextBlock Text="{Binding Path=NewStock, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Right" Margin="0,186,10,0" TextAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="20" FontWeight="Bold" Width="68"/>
    <TextBox x:Name="txtComment"  HorizontalAlignment="Left" Height="86" Margin="289,233,0,0" TextWrapping="Wrap" Text="{Binding Path=ModEntry}" VerticalAlignment="Top" Width="493"/>
    <Label Content="Comment:" HorizontalAlignment="Left" Margin="289,207,0,0" VerticalAlignment="Top"/>

原因是文本框具有默认的UpdateSourceTrigger=LostFocus,而不是PropertyChanged,以防止用户输入键入的内容进行更新。

新知识: WPF很酷,它会自动处理不可信的值,比如null或字符串,并将字段标记为红色!)

再次感谢你的链接!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53687185

复制
相关文章

相似问题

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