完全来源于十月的寒流,感谢大佬讲解
在XAML中,可以绑定到许多不同类型的数据源和属性。以下是一些可以绑定的常见数据源和属性:
-
属性:可以绑定到对象的属性,例如控件的
Text
、Visibility
、IsEnabled
等属性。 -
集合:可以绑定到集合数据,如
List
、ObservableCollection
、Array
等。在绑定到集合时,还可以使用索引器绑定到特定项。 -
静态资源:可以使用
x:Static
引用静态字段或属性,如常量、枚举、静态类的属性等。 -
数据上下文:在WPF和其他XAML框架中,每个元素都有一个数据上下文,可以在此上下文中绑定到其父元素的属性或继承的数据上下文的属性。
-
数据模型:可以绑定到MVVM(Model-View-ViewModel)模式中的数据模型,通常是一个实现
INotifyPropertyChanged
接口的类。 -
XML和JSON数据:可以绑定到XML或JSON数据,使用XMLDataProvider或ObjectDataProvider等。
-
资源字典:可以绑定到资源字典中的资源,如样式、模板、图像等。
-
命令:可以使用
Command
绑定到自定义命令,以在用户交互时执行操作。 -
视觉状态:可以绑定到不同的视觉状态,以根据应用程序的当前状态更改UI。
-
动画:可以绑定到动画属性,以在动画执行时更改UI元素的属性。
这些只是一些常见的绑定数据源,实际上,XAML绑定是非常灵活的,可以将其用于几乎任何具有属性或数据的地方。数据绑定是XAML中非常强大的特性,可以用于创建动态、交互式和可扩展的用户界面。
一、Source
<Window x:Class="BindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainWindowViewModel></local:MainWindowViewModel>
</Window.DataContext>
<Window.Resources>
</Window.Resources>
<StackPanel>
<TextBlock Text="{Binding}" FontSize="30"></TextBlock>
</StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BindingTest
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class MainWindowViewModel
{
public string Message => "this is test";
public override string ToString()
{
return "hello world";
}
}
}
后台实现binding
<Window x:Class="BindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Window.DataContext>
<local:MainWindowViewModel></local:MainWindowViewModel>
</Window.DataContext>
<Window.Resources>
</Window.Resources>
<StackPanel>
<TextBlock x:Name="tbl" FontSize="30"></TextBlock>
</StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BindingTest
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var binding = new Binding
{
Path = new PropertyPath("Message"),
Mode = BindingMode.TwoWay,
};
BindingOperations.SetBinding(tbl, TextBlock.TextProperty, binding);
}
}
public class MainWindowViewModel
{
private string message = "this is test";
public string Message
{
get { return message; }
set { message = value; }
}
}
}
绑定StaticResource资源
<Window x:Class="BindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingTest"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Window.DataContext>
<local:MainWindowViewModel></local:MainWindowViewModel>
</Window.DataContext>
<Window.Resources>
<sys:String x:Key="str">Hello, World</sys:String>
</Window.Resources>
<StackPanel>
<TextBlock x:Name="tbl" FontSize="30" Text="{Binding Source={StaticResource str}}"></TextBlock>
</StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BindingTest
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
}
public class MainWindowViewModel
{
private string message = "this is test";
public string Message
{
get { return message; }
set { message = value; }
}
}
}
使用StaticResource和DynamicResource资源
<Window x:Class="BindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingTest"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Window.DataContext>
<local:MainWindowViewModel></local:MainWindowViewModel>
</Window.DataContext>
<Window.Resources>
<sys:String x:Key="str">Hello, World</sys:String>
</Window.Resources>
<StackPanel>
<!--<TextBlock x:Name="tbl_1" FontSize="30" Text="{Binding Source={DynamicResource str}}"></TextBlock>-->
<TextBlock x:Name="tbl_2" FontSize="30" Text="{Binding Source={StaticResource str}}"></TextBlock>
<TextBlock x:Name="tbl_3" FontSize="30" Text="{DynamicResource str}"></TextBlock>
</StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BindingTest
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.Resources["str"] = "GoodBye";
}
}
public class MainWindowViewModel
{
private string message = "this is test";
public string Message
{
get { return message; }
set { message = value; }
}
}
}
<TextBlock x:Name="tbl_1" FontSize="30" Text="{Binding Source={DynamicResource str}}"></TextBlock>
这是尝试在TextBlock元素的Source属性上使用DynamicResource,但是Source属性不是DependencyProperty,因此无法直接使用DynamicResource。只能在DependencyObject的DependencyProperty上使用DynamicResource。
要在TextBlock中使用DynamicResource,应该将DynamicResource绑定到Text属性,而不是Source属性。例如,可以这样修改XAML:
<TextBlock x:Name="tbl_1" FontSize="30" Text="{DynamicResource str}"></TextBlock>
这将允许使用DynamicResource来绑定Text属性,而不会引发异常。DynamicResource通常用于将资源动态应用到具有DependencyProperty的元素,而不是Source属性。
使用属性、静态属性、常量资源
<Window x:Class="BindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingTest"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Window.DataContext>
<local:MainWindowViewModel></local:MainWindowViewModel>
</Window.DataContext>
<Window.Resources>
<sys:String x:Key="str">Hello, World</sys:String>
<local:MyResource x:Key="myres"></local:MyResource>
</Window.Resources>
<StackPanel>
<!--<TextBlock x:Name="tbl_1" FontSize="30" Text="{Binding Source={DynamicResource str}}"></TextBlock>-->
<!--<TextBlock x:Name="tbl_2" FontSize="30" Text="{Binding Source={StaticResource str}}"></TextBlock>-->
<!--<TextBlock x:Name="tbl_3" FontSize="30" Text="{DynamicResource str}"></TextBlock>-->
<TextBlock FontSize="30" Text="{Binding Source={StaticResource myres}, Path=Message}"></TextBlock>
<TextBlock FontSize="30" Text="{Binding Source={x:Static local:MyResource.StaticString}}"></TextBlock>
<TextBlock FontSize="30" Text="{Binding Source={x:Static local:MyResource.ConstString}}"></TextBlock>
</StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BindingTest
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.Resources["str"] = "GoodBye";
}
}
public class MyResource
{
public string Message { get; } = "Public Property";
public static string StaticString { get; } = "Static String";
public const string ConstString = "Const String";
}
public class MainWindowViewModel
{
private string message = "this is test";
public string Message
{
get { return message; }
set { message = value; }
}
}
}
待学习
<CollectionViewSource></CollectionViewSource>
<ObjectDataProvider></ObjectDataProvider>
二、ElementName
<Window x:Class="BindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BindingTest"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Loaded="Window_Loaded">
<Window.DataContext>
<local:MainWindowViewModel></local:MainWindowViewModel>
</Window.DataContext>
<Window.Resources>
</Window.Resources>
<StackPanel>
<TextBox FontSize="30" x:Name="txt"></TextBox>
<TextBox FontSize="30" Text="{Binding ElementName=txt, Path=Text, Mode=TwoWay}"></TextBox>
</StackPanel>
</Window>
**在上述XAML代码中,第二个试图通过绑定将其文本与第一个TextBox
的文本同步,而且将绑定模式设置为TwoWay
。理论上,这意味着当更改第二个TextBox
中的文本时,第一个TextBox
的文本也应该相应地更改。
然而,在这里遇到的问题可能是由于两个TextBox
之间的绑定路径的问题。具体来说,第二个TextBox
的绑定路径ElementName=txt, Path=Text
指示它应该与txt
元素的Text
属性进行双向绑定。这意味着它将复制txt
元素的Text
属性的值,但并不会与txt
的Text
属性绑定在一起,所以当更改第二个TextBox
的文本时,第一个TextBox
的文本不会随之更改。
如果想要实现两个TextBox
之间的文本同步,可以尝试以下修改:
<StackPanel>
<TextBox FontSize="30" x:Name="txt"></TextBox>
<TextBox FontSize="30" Text="{Binding ElementName=txt, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</StackPanel>
通过添加UpdateSourceTrigger=PropertyChanged
,可以确保当第二个TextBox
的文本更改时,立即将值传播回数据源(即第一个TextBox
的Text
属性),从而实现双向绑定。这样,当更改第二个TextBox
的文本时,第一个TextBox
的文本也会跟着变化。