【问题标题】:Access named item inside ItemTemplate访问 ItemTemplate 中的命名项目
【发布时间】:2012-05-20 04:07:34
【问题描述】:

我有以下场景:

<Button Click="ClickHandler">Click Me</Button>
<TextBox x:Name="MyInputTextBox" />
<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBox x:Name="MyRepeatTextBox" Text="{Binding}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

如果 MyRepeatTextBox.Text == MyInputTextBox.Text 我想将 MyRepeatTextBox.Background 的颜色更改为绿色。如果 MyRepeatTextBox.Text 为空白,我想将颜色更改为红色。我将如何实现按钮单击处理程序?

【问题讨论】:

    标签: windows-8 datatemplate itemscontrol winrt-xaml itemtemplate


    【解决方案1】:

    不确定按钮事件是否最适合。

    由于 DataTriggers 再次没有被带到 WPF 世界之外,所以它们已经被淘汰了。也没有 IMultiValueConverter。行为目前不存在,但有一个不错的 codeplex project 供他们使用。我会用那个

    public class MatchTextForegroundBehaviour : Behavior<TextBox>
    {
        private TextBox _attachedElement;
    
        public static readonly DependencyProperty MatchForegroundProperty =
            DependencyProperty.Register("MatchForeground", typeof(Brush),
            typeof(MatchTextForegroundBehaviour),
            new PropertyMetadata(new SolidColorBrush(Colors.Green), OnMatchForegroundChanged));
    
        public static readonly DependencyProperty FallbackForegroundProperty =
            DependencyProperty.Register("FallbackForeground", typeof(Brush),
            typeof(MatchTextForegroundBehaviour),
            new PropertyMetadata(new SolidColorBrush(Colors.Black), OnFallbackForegroundChanged));
    
        public static readonly DependencyProperty TextToMatchProperty =
            DependencyProperty.Register("TextToMatch", typeof(string),
            typeof(MatchTextForegroundBehaviour),
            new PropertyMetadata(null, OnTextToMatchChanged));
    
        public Brush MatchForeground
        {
            get { return (Brush)GetValue(MatchForegroundProperty); }
            set { SetValue(MatchForegroundProperty, value); }
        }
    
        public Brush FallbackForeground
        {
            get { return (Brush)GetValue(FallbackForegroundProperty); }
            set { SetValue(FallbackForegroundProperty, value); }
        }
    
        public string TextToMatch
        {
            get { return (string)GetValue(TextToMatchProperty); }
            set { SetValue(TextToMatchProperty, value); }
        }
    
        /// <summary>
        /// Event when the behavior is attached to a element.
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            _attachedElement = AssociatedObject;
            if(_attachedElement != null)
                _attachedElement.TextChanged += (s,e) => ChangeForeground();
        }
    
        private static void OnMatchForegroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = (MatchTextForegroundBehaviour)d;
    
            behavior.ChangeForeground();
        }
    
        private static void OnTextToMatchChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = (MatchTextForegroundBehaviour)d;
    
            behavior.ChangeForeground();
        }
    
        private static void OnFallbackForegroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = (MatchTextForegroundBehaviour)d;
    
            behavior.ChangeForeground();
        }
    
    
        private void ChangeForeground()
        {
            if (_attachedElement == null) return;
            if (string.IsNullOrEmpty(TextToMatch)) return; // change foreground to red?
    
            if (_attachedElement.Text == TextToMatch)
            {
                _attachedElement.Foreground = MatchForeground;
            }
            else
            {
                _attachedElement.Foreground = FallbackForeground;
            }
        }
    }
    

    还有xaml

    <TextBox x:Name="MyRepeatTextBox" Text="{Binding}" 
             TextToMatch="{Binding Text, ElementName=MyInputTextBox}"
             FallbackForeground="Black" MatchForeground="Green" />
    

    如果一个按钮点击事件是真的你想怎么做的,你可以试试下面的。我没有针对 WinRT 编译这个,但我认为使用的所有内容都在 WinRT 中。

    使用下面的扩展方法

    internal static class TreeExtensions
    {
        public static T GetChildElement<T>(this DependencyObject element) where T :FrameworkElement
        {
            if (element == null) return null;
            if(element.GetType() == typeof(T)) return (T)element;
    
            T childAsT = null;
            int count = VisualTreeHelper.GetChildrenCount(element);
            for (int i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(element, i);
                childAsT = child.GetChildElement<T>();
                if (childAsT != null) break;
            }
            return childAsT;
        }
    }
    

    在按钮单击事件中,您将执行以下操作(假设您为 ItemsControl 指定了 itemsControl 的名称:

            foreach (var item in itemsControl.Items)
            {
                var element = itemsControl.ItemContainerGenerator.ContainerFromItem(item);
                var textblock = element.GetChildElement<TextBlock>();
                if (textblock != null)
                {
                    if (textblock.Text == MyInputTextBox.Text)
                        textblock.Foreground = new SolidColorBrush(Colors.Green);
                    else
                        textblock.Foreground = new SolidColorBrush(Colors.Black);
                }
            }
    

    【讨论】:

    • 谢谢!你能从外部按钮的点击处理程序的角度解决这个问题吗?这可能吗?
    猜你喜欢
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多