WPF中的多重绑定
MultiBinding 将会给后端传回一个数组, 其顺序为绑定的顺序. 例如:
<DataGrid
Margin="10"
AutoGenerateColumns="False"
ItemsSource="{Binding Stu}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="Id" />
<DataGridTextColumn Binding="{Binding Name}" Header="Name" />
<DataGridTextColumn Binding="{Binding Age}" Header="Age" />
<DataGridTextColumn Binding="{Binding Description}" Header="Description" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button
Width="60"
HorizontalAlignment="Center"
Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.MyButtonCommand}"
CommandParameter="{Binding}"
Content="申请">
<Button.Style>
<Style TargetType="Button">
<!--<Setter Property="IsEnabled" Value="{Binding Age, Converter={StaticResource SingleParamConverter}}" />-->
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding Converter="{StaticResource MultiParamConverter}">
<Binding Path="Age"/>
<Binding Path="Id"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
在这里的 Button 的isEnabled属性用了多重绑定给converter, 用来筛选条件
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding Converter="{StaticResource MultiParamConverter}">
<Binding Path="Age"/>
<Binding Path="Id"/>
</MultiBinding>
</Setter.Value>
</Setter>
这时 后端转换器为:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace NavTest.Components
{
public class MultiParamConverter : IMultiValueConverter
{
public object Convert(
object[] values,
Type targetType,
object parameter,
CultureInfo culture
)
{
int age;
int id;
if (values == null)
{
return true;
}
int.TryParse(values[0].ToString(), out age);
int.TryParse(values[1].ToString(), out id);
if (age > 1 && id > 5)
{
return true;
}
return false;
}
public object[] ConvertBack(
object value,
Type[] targetTypes,
object parameter,
CultureInfo culture
)
{
throw new NotImplementedException();
}
}
}
效果:
完整代码:
view:
<UserControl
x:Class="NavTest.Views.Page5"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cv="clr-namespace:NavTest.Components"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:NavTest.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mv="clr-namespace:NavTest.ViewModels"
d:DataContext="{d:DesignInstance mv:Page5ViewModel}"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Resources>
<cv:SingleParamConverter x:Key="SingleParamConverter" />
<cv:MultiParamConverter x:Key="MultiParamConverter" />
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<DataGrid
Margin="10"
AutoGenerateColumns="False"
ItemsSource="{Binding Stu}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="Id" />
<DataGridTextColumn Binding="{Binding Name}" Header="Name" />
<DataGridTextColumn Binding="{Binding Age}" Header="Age" />
<DataGridTextColumn Binding="{Binding Description}" Header="Description" />
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button
Width="60"
HorizontalAlignment="Center"
Command="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext.MyButtonCommand}"
CommandParameter="{Binding}"
Content="申请">
<Button.Style>
<Style TargetType="Button">
<!--<Setter Property="IsEnabled" Value="{Binding Age, Converter={StaticResource SingleParamConverter}}" />-->
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding Converter="{StaticResource MultiParamConverter}">
<Binding Path="Age"/>
<Binding Path="Id"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
viewModel:
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using NavTest.Eneities;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace NavTest.ViewModels
{
public partial class Page5ViewModel:ObservableObject
{
public Page5ViewModel()
{
for (int i = 0; i < 10; i++)
{
Stu.Add(new()
{
Id = i + 2,
Age = $"{i}",
Name = $"Name{i}",
Description = $"Description{i}"
});
}
}
[ObservableProperty]
private ObservableCollection<Student> stu = new();
[RelayCommand]
public void MyButton(Student s)
{
MessageBox.Show(s.Name);
}
}
}
转换器:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace NavTest.Components
{
public class MultiParamConverter : IMultiValueConverter
{
public object Convert(
object[] values,
Type targetType,
object parameter,
CultureInfo culture
)
{
int age;
int id;
if (values == null)
{
return true;
}
int.TryParse(values[0].ToString(), out age);
int.TryParse(values[1].ToString(), out id);
if (age > 1 && id > 5)
{
return true;
}
return false;
}
public object[] ConvertBack(
object value,
Type[] targetTypes,
object parameter,
CultureInfo culture
)
{
throw new NotImplementedException();
}
}
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace NavTest.Components
{
public class SingleParamConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return true;
}
int age;
int.TryParse(value.ToString(), out age);
if (age > 5)
{
return true;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}