//定义三个转换器
public class ButtonBackgroundChanged : IMultiValueConverter
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
if (values[1] == DependencyProperty.UnsetValue)
return new System.Windows.Media.Imaging.BitmapImage(new Uri("pack://application:,,,/当前项目名称;component/Images/WhiteButton.png"));
AnalysisBtn analysisBtn = (AnalysisBtn)values[0];
string geneName = values[1].ToString().Substring(0, 3);
if (geneName == analysisBtn.ToString())
return new System.Windows.Media.Imaging.BitmapImage(new Uri("pack://application:,,,/当前项目名称;component/Images/BlueButton.png"));
return new System.Windows.Media.Imaging.BitmapImage(new Uri("pack://application:,,,/当前项目名称;component/Images/WhiteButton.png"));
catch(Exception)
throw;
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
return null;
public class ButtonImageChanged : IMultiValueConverter
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
if (values[1] == DependencyProperty.UnsetValue)
if(values[2].ToString() == "button1")
return new System.Windows.Media.Imaging.BitmapImage(new Uri("pack://application:,,,/当前项目名称;component/Images/FAM_Black.png"));
return new System.Windows.Media.Imaging.BitmapImage(new Uri("pack://application:,,,/当前项目名称;component/Images/VIC_Black.png"));
AnalysisBtn analysisBtn = (AnalysisBtn)values[0];
string geneName = values[1].ToString().Substring(0, 3);
if (geneName == analysisBtn.ToString())
return new System.Windows.Media.Imaging.BitmapImage(new Uri(string.Format("pack://application:,,,/当前项目名称;component/Images/{0}_White.png",geneName)));
return new System.Windows.Media.Imaging.BitmapImage(new Uri(string.Format("pack://application:,,,/当前项目名称;component/Images/{0}_Black.png", geneName)));
catch (Exception)
throw;
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
return null;
public class TextForegroundChanged : IMultiValueConverter
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
if (values[1] == DependencyProperty.UnsetValue)
return new SolidColorBrush(Colors.Black);
AnalysisBtn analysisBtn = (AnalysisBtn)values[0];
string geneName = values[1].ToString().Substring(0, 3);
if (geneName == analysisBtn.ToString())
return new SolidColorBrush(Colors.White);
return new SolidColorBrush(Colors.Black);
catch (Exception)
throw;
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
return null;
为什么说这个图很复杂呢,明明跟上面的例子一模一样,主要是这个第二第三个按钮,他是动态的,不仅文字动态,他左边那个小图标“F”样子的那个也要变,而且点击了之后背景变了之后,这个小图标也要变,因为他是黑底的,要改为白底。
上面这种用模板的实现方式还是太复杂了,可以不要参考了,实际上,使用依赖属性就能做到,而且非常简单。我参考了WPF依赖属性的正确学习方法
先自定义一个MyButton继承Button
public class MyButton : Button
public static readonly DependencyProperty ForeImageProperty = DependencyProperty.Register(nameof(ForeImage), typeof(string), typeof(MyButton), new PropertyMetadata(null));
public static readonly DependencyProperty BackImageProperty = DependencyProperty.Register(nameof(BackImage), typeof(string), typeof(MyButton), new PropertyMetadata(null));
public string ForeImage
get { return (string)GetValue(ForeImageProperty); }
set { SetValue(ForeImageProperty, value); }
public string BackImage
get { return (string)GetValue(BackImageProperty); }
set { SetValue(BackImageProperty, value); }
然后定义一个style修改他的模板
<Style TargetType="{x:Type local:MyButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Height="34" MinWidth="97" Name="dpBtn">
<Grid.Background>
<ImageBrush ImageSource="/Images/BlueButton.png" Stretch="Fill" TileMode="None" />
</Grid.Background>
<StackPanel Orientation="Horizontal">
<Image Name="img" Source="{Binding ForeImage, RelativeSource={x:Static RelativeSource.TemplatedParent}}" Width="16" Height="16" Margin="10,0,0,0"/>
<TextBlock Name="txt" Text="{Binding Content, RelativeSource={x:Static RelativeSource.TemplatedParent}}" TextWrapping="Wrap" FontSize="16" Foreground="White" VerticalAlignment="Center" Margin="5,0,5,0"/>
</StackPanel>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsMouseOver,RelativeSource={x:Static RelativeSource.Self}}" Value="True">
<Setter Property="Background" TargetName="dpBtn">
<Setter.Value>
<ImageBrush ImageSource="/Images/BlueButton.png" Stretch="Fill" TileMode="None" />
</Setter.Value>
</Setter>
<Setter Property="Source" TargetName="img" Value="{Binding ForeImage, RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>
<Setter Property="Foreground" TargetName="txt" Value="white"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsMouseOver,RelativeSource={x:Static RelativeSource.Self}}" Value="False">
<Setter Property="Background" TargetName="dpBtn">
<Setter.Value>
<ImageBrush ImageSource="/Images/WhiteButton.png" Stretch="Fill" TileMode="None" />
</Setter.Value>
</Setter>
<Setter Property="Source" TargetName="img" Value="{Binding BackImage, RelativeSource={x:Static RelativeSource.TemplatedParent}}"/>
<Setter Property="Foreground" TargetName="txt" Value="black"/>
</DataTrigger>
<Trigger Property="IsEnabled" Value="true"/>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="Gray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
主界面调用
<StackPanel x:Name="analysispanel" Orientation="Horizontal">
<local:MyButton x:Name="bt1" ForeImage="/Images/Camera_White.png" BackImage="/Images/Camera_Black.png" Content="相机" Height="34" MinWidth="97"/>
<local:MyButton x:Name="bt2" ForeImage="/Images/AllAnalysis_White.png" BackImage="/Images/AllAnalysis_Black.png" Content="全部分析" Height="34" MinWidth="97"/>
<local:MyButton x:Name="bt3" ForeImage="/Images/Analysis_White.png" BackImage="/Images/Analysis_Black.png" Content="分析" Height="34" MinWidth="97"/>
<local:MyButton x:Name="bt4" ForeImage="/Images/Import_White.png" BackImage="/Images/Import_Black.png" Content="导入" Height="34" MinWidth="97"/>
</StackPanel>
其他还可以参考微软官方的通过创建 ControlTemplate 自定义现有控件的外观
WPF多个按钮点击切换样式本文主要讲述WPF中多个按钮,点击状态为一个样式,未点击状态为一个样式,两种样式通过点击这个动作会发生改变,点击另一个按钮,当前已点击的按钮样式也改变的情况。不复杂样式的多个按钮主要做法就是将按钮使用radiobutton来代替,然后各个radiobutton的GroupName取名为同一个,如本例中就是取名为“button1”。&amp;lt;RadioButton ...
IValueConverter类 Bingding.Converter
https://www.cnblogs.com/gaoshang212/p/4973300.html?utm_source=tuicool&utm_medium=referral
1.需求说明
显示界面上有多个RadioButton,需要选择其中一个来修改一个枚举类型的值。举例:有七个RadioButton,星期一到星期日,选择其中之一可以改变枚举类型week的对应值。
2.实现方法
利用Converter...
1.StackPanel WrapPanel DockPanel
StackPanel
<!--排列成一行或一列 StackPanel 默认排列方向 :垂直 水平:高度与父窗口的高度相同
子元素超出部分会被隐藏-->
<!--<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button>按钮1</Button>
<Button Marg
好的,关于WPF运行时动态切换ItemsControl.ItemsPanel的问题,我可以为您提供以下思路:
1. 创建多个ItemsPanel,例如:StackPanel、WrapPanel、UniformGrid等。
2. 在XAML文件中,使用Resources定义这些ItemsPanel。
3. 创建一个ItemsControl,并在ItemsControl中使用DataTemplate来定义Item的样式。
4. 在ItemsControl中,使用一个默认的ItemsPanel。
5. 在运行时,根据需要动态切换ItemsControl的ItemsPanel。
6. 在切换时,先从ItemsControl的Resources中获取要切换的ItemsPanel,然后将其设置为ItemsControl的ItemsPanel。
以下是一个简单的示例代码:
```xml
<!--MainWindow.xaml-->
<Window>
<Window.Resources>
<ItemsPanelTemplate x:Key="StackPanelTemplate">
<StackPanel/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="WrapPanelTemplate">
<WrapPanel/>
</ItemsPanelTemplate>
<ItemsPanelTemplate x:Key="UniformGridTemplate">
<UniformGrid/>
</ItemsPanelTemplate>
</Window.Resources>
<StackPanel>
<StackPanel Orientation="Horizontal">
<Button Content="StackPanel" Click="StackPanel_Click"/>
<Button Content="WrapPanel" Click="WrapPanel_Click"/>
<Button Content="UniformGrid" Click="UniformGrid_Click"/>
</StackPanel>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<!--默认的ItemsPanel-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
</Window>
```csharp
//MainWindow.xaml.cs
public partial class MainWindow : Window
public ObservableCollection<string> Items { get; set; }
public MainWindow()
InitializeComponent();
Items = new ObservableCollection<string>() { "Item 1", "Item 2", "Item 3" };
DataContext = this;
private void StackPanel_Click(object sender, RoutedEventArgs e)
ItemsControl.ItemsPanel = (ItemsPanelTemplate)Resources["StackPanelTemplate"];
private void WrapPanel_Click(object sender, RoutedEventArgs e)
ItemsControl.ItemsPanel = (ItemsPanelTemplate)Resources["WrapPanelTemplate"];
private void UniformGrid_Click(object sender, RoutedEventArgs e)
ItemsControl.ItemsPanel = (ItemsPanelTemplate)Resources["UniformGridTemplate"];
在这个示例中,我们创建了三个不同的ItemsPanel,分别是StackPanel、WrapPanel和UniformGrid,然后在XAML文件中使用Resources定义它们。在MainWindow中,我们创建了一个ItemsControl,并在ItemsControl中使用DataTemplate来定义Item的样式,同时设置了一个默认的ItemsPanel。
在运行时,我们通过点击按钮来动态切换ItemsControl的ItemsPanel。在每个按钮的Click事件中,我们从MainWindow的Resources中获取要切换的ItemsPanel,然后将其设置为ItemsControl的ItemsPanel。
希望以上思路能够对您有所帮助。
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="IsSelectionActive" Value="false" />
</MultiTrigger.Conditions>
<!--这个是选中的颜色-->
<Setter Property="Background" TargetName="Bd" Value="#f3f3ff" />
<Setter Property="Foreground" Value="Black" />
</MultiTrigger>
WPF中TextBox更改完了之后进行操作
抹茶芭菲:
WPF自定义最大化最小化关闭按钮
迷惘小书童: