首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WinUI-3和C# <>澄清:如何绕过NumberBox中忽略的UpdateSourceTrigger

WinUI-3和C# <>澄清:如何绕过NumberBox中忽略的UpdateSourceTrigger
EN

Stack Overflow用户
提问于 2022-10-10 20:06:14
回答 2查看 81关注 0票数 0

更新:感谢安德鲁KeepCoding的CustomNumberBox类。这确实很有用,而且比另一种解决方案更容易使用。它不需要数据绑定就能工作。

我对克里斯·夏勒提出的问题有一个澄清/用户错误,由理查德·张回答:How to work around UpdateSourceTrigger ignored in NumberBox

我收到以下两个错误:

Error CS1061 'NumberBox‘不包含'VisualTreeFindName’的定义,也找不到接受'NumberBox‘类型的第一个参数的可访问扩展方法'VisualTreeFindName’(您是缺少使用指令还是程序集引用?)

错误CS0103名称“Model”在当前上下文中不存在

下面是前一个答案的扩展(尽管我的是名称空间会计..)

代码语言:javascript
复制
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
using System;

namespace Accounting
{
    public static class StaticExtension
    {
        public static FrameworkElement VisualTreeFindName(this DependencyObject element, string name)
        {
            if (element == null || string.IsNullOrWhiteSpace(name))
            {
                return null;
            }
            if (name.Equals((element as FrameworkElement)?.Name, StringComparison.OrdinalIgnoreCase))
            {
                return element as FrameworkElement;
            }
            var childCount = VisualTreeHelper.GetChildrenCount(element);
            for (int i = 0; i < childCount; i++)
            {
                var result = VisualTreeHelper.GetChild(element, i).VisualTreeFindName(name);
                if (result != null)
                {
                    return result;
                }
            }
            return null;
        }
    }
}

这是MainWindow.xaml

代码语言:javascript
复制
<Window
    x:Class="Accounting.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Accounting"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
        <NumberBox
            x:Name="myNumberBox"
            SpinButtonPlacementMode="Compact"
            Loaded="NumberBox_Loaded"
            Value="0" />
    </StackPanel>
</Window>

这是MainWindow.xaml.cs

代码语言:javascript
复制
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using System;
using System.Linq;
using System.Reflection; 

namespace Accounting
{
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }

        private void NumberBox_Loaded(object sender, RoutedEventArgs e)
        {
            var box = sender as NumberBox;
            var textBox = box.VisualTreeFindName<TextBox>("InputBox");
            textBox.TextChanged += TextBox_TextChanged;
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            string text = (sender as TextBox).Text;
            bool isNumber = !text.Any(t => !char.IsDigit(t));
            if (isNumber)
            {
                double.TryParse(text, out double value);
                if (value != Model.Value)
                    Model.Value = value;
            }
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-11 01:19:03

您还可以创建这样的自定义控件。这里的一个缺点是它将始终以UpdateSourceTrigger=PropertyChanged的形式工作。

代码语言:javascript
复制
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using System.Collections.Generic;
using System.Linq;

namespace NumberBoxes;

public class CustomNumberBox : NumberBox
{
    public CustomNumberBox()
    {
        Loaded += CustomNumberBox_Loaded;
    }

    private static IEnumerable<T> FindChildrenOfType<T>(DependencyObject parent) where T : DependencyObject
    {
        if (parent is ContentControl contentControl)
        {
            if (contentControl.Content is T tContent)
            {
                yield return tContent;
            }

            if (contentControl.Content is DependencyObject dependencyObjectContent)
            {
                foreach (T grandChild in FindChildrenOfType<T>(dependencyObjectContent))
                {
                    yield return grandChild;
                }
            }
        }
        else
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);

                if (child is T tChild)
                {
                    yield return tChild;
                }

                foreach (T grandChild in FindChildrenOfType<T>(child))
                {
                    yield return grandChild;
                }
            }
        }
    }

    private void CustomNumberBox_Loaded(object sender, RoutedEventArgs e)
    {
        if (FindChildrenOfType<TextBox>(this)
            .Where(x => x.Name is "InputBox")
            .FirstOrDefault() is TextBox inputBox)
        {
            inputBox.TextChanged += InputBox_TextChanged;
        }
    }

    private void InputBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (sender is TextBox inputBox)
        {
            Text = inputBox.Text;
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2022-10-10 22:30:43

Error CS1061 'NumberBox‘不包含'VisualTreeFindName’的定义,也找不到接受'NumberBox‘类型的第一个参数的可访问扩展方法'VisualTreeFindName’(您是缺少使用指令还是程序集引用?)

您会得到这个错误,因为方法VisualTreeFindName不是一个通用的方法,并且在调用它时不想要<TextBox>。删除<TextBox>并将返回转换为TextBox应该有效,并在NumberBox中给出名为InputBoxTextBox

代码语言:javascript
复制
if (this.ThisNumberBox.VisualTreeFindName("InputBox") is TextBox inputBox)
{
    inputBox.TextChanged += InputBox_TextChanged;
}

错误CS0103名称“Model”在当前上下文中不存在

您会得到此错误,因为代码中不存在Model。这个模型只是一个属性,用于您用作引用的问题中。用目标属性替换Model应该可以做到这一点。

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

https://stackoverflow.com/questions/74020198

复制
相关文章

相似问题

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