«Тег» ... Специальный функционал в WPF? - PullRequest
6 голосов
/ 04 августа 2011

MSDN говорит: «Получает или задает произвольное значение объекта, которое можно использовать для хранения пользовательской информации об этом элементе». Это означает, что я могу хранить все, что захочу, в этом свойстве.

Но если вы связываетесь с этим свойством (со свойством типа String, имеющим значение «XYZ») и используете его в условиях триггера, оно не работает!

  <Trigger Property="Tag" Value="XYZ">
      <Setter Property="Background" Value="Red" />
  </Trigger>

Не устанавливает красный фон. Вы можете попытаться предположить, что myElement является TextBlock! Почему это так?

Ответы [ 3 ]

7 голосов
/ 04 августа 2011

Tag - это конструкция, сохраняемая со дней Winforms (и, возможно, там до этого!).Он использовался как удобное место для связывания объекта с элементом пользовательского интерфейса, таким как FileInfo с Button, поэтому в обработчике событий Button вы могли просто взять отправителя события, привести его к Button, а затем привести Tagзначение для FileInfo, и у вас есть все, что вам нужно для файла, который вы хотите открыть.

Существует одна ситуация , но я обнаружил, что Tag полезен в WPF,Я использовал его в качестве места ожидания, к которому может получить доступ элемент MenuMenu ContextMenu, который не может использовать обычные привязки RelativeSource, которые вы использовали бы для обхода визуального дерева.

<ListBox.ItemContainerStyle>
        <Style
            TargetType="ListBoxItem">
            <Setter
                Property="Tag"
                Value="{Binding ElementName=TheUserControlRootElement}" />
            <Setter
                Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu>
                        <MenuItem
                            Header="_Remove"
                            ToolTip="Remove this from this list"
                            CommandParameter="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                            Command="{Binding PlacementTarget.Tag.Remove, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>

Из ContextMenu, Я не могу получить доступ к команде Remove , которая определена в классе UserControl, где определен этот фрагмент.Но я могу связать корень с Tag из ListBoxItem, к которому я могу получить доступ через свойство ContextMenu.PlacementTarget.Тот же трюк может использоваться при связывании в пределах ToolTip, поскольку применяются те же ограничения.

7 голосов
/ 04 августа 2011

Тег не имеет специальной функциональности в WPF.

Это работает для меня:

<TextBlock Tag="{Binding Data}"
           x:Name="tb">
    <TextBlock.Style>
        <Style>
            <Style.Triggers>
                <Trigger Property="TextBlock.Tag"
                         Value="XYZ">
                     <Setter Property="TextBlock.Background"
                             Value="Lime" />
                </Trigger>
            </Style.Triggers>        
        </Style>
    </TextBlock.Style>
</TextBlock>

И присвоение свойству объекта данных значения "XYZ" в событии.

2 голосов
/ 04 августа 2011

MainWindow.xaml:

<Window x:Class="wpftest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock x:Name="test" MouseDown="test_MouseDown"
                   Tag="{Binding TestProperty}">
            <TextBlock.Style>
                <Style TargetType="{x:Type TextBlock}">
                    <Style.Triggers>
                        <Trigger Property="Tag" Value="XYZ">
                            <Setter Property="Background" Value="Red" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
    </Grid>
</Window>

MainWindow.xaml.cs:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = new TestViewModel();
    }

    private void test_MouseDown(object sender, MouseButtonEventArgs e)
    {
        ((TestViewModel)DataContext).TestProperty = "XYZ";
    }

    private sealed class TestViewModel : INotifyPropertyChanged
    {
        private string _testPropertyValue;

        public string TestProperty
        {
            get { return _testPropertyValue; }
            set
            {
                _testPropertyValue = value;
                var handler = PropertyChanged;
                if(handler != null)
                    handler(this, new PropertyChangedEventArgs("TestProperty"));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

Обновлено: свойство Tag теперь привязано к TestProperty.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...