wpf中怎么是鼠标移动到textblock中的字体上使其改变颜色

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wpf中怎么是鼠标移动到textblock中的字体上使其改变颜色相关的知识,希望对你有一定的参考价值。

给你写个例子
用除法器
当鼠标移到文字上时候改变颜色
<TextBlock Text="TestColor" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
参考技术A RouteEvent,route mouse的mouseover event,这个用style最好做了,设置两个Trigger

WPF 将 TextBlock 绑定到自己 ViewModel 中的特定列表项

【中文标题】WPF 将 TextBlock 绑定到自己 ViewModel 中的特定列表项【英文标题】:WPF Bind TextBlock to Specific Item of List in own ViewModel 【发布时间】:2022-01-23 21:23:09 【问题描述】:

我是 WPF 新手,在尝试将多个 TextBlocks 绑定到我的“ItemViewModel”-List 的属性时遇到了问题。

HomeView.xaml 是一个用户控件,显示在主窗口上。 我在所有数据所在的位置创建了自己的 HomeViewModel.cs,因此我不使用 HomeView.xaml.cs,也没有更改该代码中的任何内容。

我的目标是,每当“HomeViewModel.cs”中的“_items[i]._weight”或“_items[i]._count”的值发生变化时,“HomeView.xaml”中的绑定 TextBlock 或 TextBox将获得新值。

另外,例如,我如何告诉“item1WeightTBx”它绑定到“_items[0]._weight”而不是“_items[3]._weight “?

到目前为止,“HomeView.xaml”一直在“HomeView”而不是“HomeViewModel”中寻找数据。

如果您需要更多代码或信息,请告诉我 :)

提前谢谢你!

HomeView.xaml(用户控制)

<UserControl x:Class="Project.MVVM.View.HomeView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:viewModel="clr-namespace:Project.MVVM.ViewModel"
             xmlns:local="clr-namespace:Project.MVVM.View"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="109*"/>
            <RowDefinition Height="156*"/>
            <RowDefinition Height="185*"/>
        </Grid.RowDefinitions>

        <TextBox x:Name="item1WeightTBx"
                 Grid.Row="2"
                 HorizontalAlignment="Left"
                 HorizontalContentAlignment="Center"
                 VerticalContentAlignment="Center"
                 DataContext="Binding Items"
                 Text="Binding _weight"
                 Height="23" 
                 Margin="51,39,0,0"
                 TextWrapping="Wrap"
                 VerticalAlignment="Top"
                 Width="40"
                 FontSize="14"/>

        <TextBlock x:Name="item1CountTBk"
                   HorizontalAlignment="Left"
                   Grid.Row="2"
                   Height="28"
                   Margin="51,65,0,0"
                   TextWrapping="Wrap"
                   DataContext="Binding Items"
                   Text="Binding _count"
                   VerticalAlignment="Top"
                   Width="57"
                   FontSize="16"
                   Foreground="#424242"/>

        <TextBox x:Name="item2WeightTBx"
                 Grid.Row="2"
                 HorizontalAlignment="Left"
                 HorizontalContentAlignment="Center"
                 VerticalContentAlignment="Center"
                 DataContext="Binding Items"
                 Text="Binding _weight"
                 Height="23" 
                 Margin="123,39,0,0"
                 TextWrapping="Wrap"
                 VerticalAlignment="Top"
                 Width="40"
                 FontSize="14"/>

        <TextBlock x:Name="item2CountTBk"
                   HorizontalAlignment="Left"
                   Grid.Row="2"
                   Height="28"
                   Margin="123,65,0,0"
                   TextWrapping="Wrap"
                   DataContext="Binding Items"
                   Text="Binding _count"
                   VerticalAlignment="Top"
                   Width="57"
                   FontSize="16"
                   Foreground="#424242"/>

                   .
                   .
                   .

HomeViewModel.cs

        public List<ItemViewModel> _items;

        public List<ItemViewModel> Items => _items;


public HomeViewModel(Connection connectionInterface, ShelfComp shelfComp)
        
            _connectioninterface = connectionInterface;
            _scale = new Scale("0,0;0,0", ShelfWidth);
            _shelfComp = shelfComp;
            

            for (int i = 0; i < shelfComp.ItemList.Count; i++)
            
                _items.Add(new ItemViewModel(_shelfComp.ItemList[i]));
             
        

ItemViewModel.cs

class ItemViewModel : ObservableObject
    
        public Item _item;

        public string _name => _item.Name;
        public int _minIndex => _item.MinIndex;
        public int _maxIndex => _item.MaxIndex;
        public double _weight => _item.Weight;
        public int Width => _item.Width;
        public int _count => _item.Count;

        public ItemViewModel(Item item)
        
            _item = item;
        
    

Item.cs

public class Item
    
        public string Name  get; set; 
        public int MinIndex  get; set; 
        public int MaxIndex  get; set; 
        public double Weight  get; 
        public int Width  get; 
        public int Count  get; set; 


        public Item(string Name, int MinIndex, int Width, double Weight)
        
            this.Name = Name;
            this.MinIndex = MinIndex;
            this.Width = Width;
            this.MaxIndex = MinIndex + Width;
            this.Weight = Weight;
            Count = 0;
        

    

ObservableObject.cs

class ObservableObject : INotifyPropertyChanged
    
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        
    

【问题讨论】:

您应该使用带有支持字段的完整属性,并且每次设置属性值时,您都需要调用OnPropertyChanged() 顺便不用重新发明***,看看Microsoft.Toolkit.Mvvm库:docs.microsoft.com/en-us/windows/communitytoolkit/mvvm/… 【参考方案1】:

您必须始终引发INotifyPropetyChanged.PropertyChanged 事件才能更新绑定。单独实现界面只是故事的一半。每个应该支持动态绑定的属性都必须引发事件。

当你组合一个类型并使用成员委托时,组合成员的实例必须是private。否则,委托是多余的,因为调用者可以绕过类 API 并直接改变实例甚至覆盖实例。如果你想隐藏Item,属性必须private。 此外,永远不要定义 public 字段。目前ItemViewModel.Item 是一个public 字段。它必须是private 和一个属性。public 属性或public 通常的成员,必须使用 PascalCase 命名。 _camelCase 表示法仅用于私有字段。

同样适用于HomeViewModel 成员:

public List<ItemViewModel> _items;
public List<ItemViewModel> Items => _items;

这是毫无意义的。这是不对的。支持字段必须是 private(记住:没有 public 字段!)。此外,由于这是一个只读属性(它只有一个get()),所以支持字段是多余的。您可以改用只读自动属性:

// Initialize from constructor
public List<ItemViewModel> Items  get; 

请记住,构造函数必须快速执行。构造函数中必须避免长时间运行的for 循环。

要解决您的绑定问题,请确保绑定源上的每个属性都会引发 INotifyPropetyChanged.PropertyChanged 事件:

ItemViewModel.cs

class ItemViewModel : ObservableObject

  private Item Item  get; 

  // Repeat this pattern for all remainig properties
  public string Name
  
     get => Item.Name;
     set
     
       Item.Name = value;
       OnPropertyChanged();
     
  

  public ItemViewModel(Item item)
  
     Item = item;
  

【讨论】:

以上是关于wpf中怎么是鼠标移动到textblock中的字体上使其改变颜色的主要内容,如果未能解决你的问题,请参考以下文章

WPF Grid响应鼠标事件

如何将 TextBlock(字体大小)增大/缩小到 WPF 中的可用空间?

WPF TextBlock 字体调整大小以填充网格中的可用空间

WPF如何改变GridView字体大小

XP系统下WPF程序字体大小不一的问题

VS2010 WPF TextBlock怎么设置字间距