五种绑定方式"/>
WPF常用的五种绑定方式
1, ElementName 根据控件的x: Name 绑定
2, RelativeSource 相对于本身或者父元素
3,StaticResource 绑定静态资源
4,ItemSource,绑定到集合元素
5,DataContent,数据源绑定
主要说明1,2,4
举例说明:
前端代码:
DataContext="{Binding Source={StaticResource Locator}, Path=ReportData}"<Grid Grid.Row="1" Grid.Column="3"><DockPanel x:Name="testDock" Margin="5,5,5,5"><Label Content="{Binding Float2}" Foreground="White" /><Button Width="auto" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DockPanel}, Path=Name}" /><ButtonWidth="auto"Margin="{Binding ElementName=TestTBlock, Path=Margin}"Background="{Binding ElementName=TestTBlock, Path=Foreground}"Content="{Binding ElementName=TestTBlock, Path=Name}" /><ButtonWidth="auto"Command="{Binding TestBtn}"CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DockPanel}}"Content="{Binding TestStr}" /><Button Width="auto" Command="{Binding TestBtn1}" CommandParameter="{Binding}" Content="{Binding TestStr2}"/></DockPanel></Grid>
1, ElementName 根据控件的x: Name 绑定
<ButtonWidth="auto"Margin="{Binding ElementName=TestTBlock, Path=Margin}"Background="{Binding ElementName=TestTBlock, Path=Foreground}"Content="{Binding ElementName=TestTBlock, Path=Name}" />
绑定了父元素 DockPanel x:Name=“testDock”,将按钮的Content 置为DockPanel 的名字
效果为:
2,RelativeSource
<ButtonWidth="auto"Command="{Binding TestBtn}"CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DockPanel}}"Content="{Binding TestStr}" />
后端代码:
public RelayCommand<DockPanel> TestBtn{get{return new RelayCommand<DockPanel>((s) =>{if (!(s is DockPanel dock)){return;}TestStr = s.Name; //必须是属性变化才能});}}private string testStr;public string TestStr{get { return testStr; }set { testStr = value; RaisePropertyChanged(); }}
找到父元素,并将父元素的本身 当做参数传递进后端(s),然后将父元素的s.Name赋值给TestStr ,TestStr 绑定前端Button的Content,有属性变化就通知前端
效果:
点击前
点击后
注意
<Button Width="auto" Command="{Binding TestBtn1}" CommandParameter="{Binding}" Content="{Binding TestStr2}"/>
的写法
CommandParameter=“{Binding}” 绑定的path为空,会把Button的数据源当参数传出去。button的数据源是
DataContext="{Binding Source={StaticResource Locator}, Path=ReportData}"
也就是 ReportDataViewModel
注意后台代码:
private string testStr2;public string TestStr2{get { return testStr2; }set { testStr2 = value; RaisePropertyChanged(); }}public RelayCommand<ReportDataViewModel> TestBtn1{get {return new RelayCommand<ReportDataViewModel>((r) =>{if (!(r is ReportDataViewModel re)){return;}TestStr2 = r.float2; //尽量用属性的变换testStr2 = r.float2;//不显示});}}
把按钮自身当参数传出去
<ButtonWidth="150"Margin="5,5,5,5"Command="{Binding Conn}"CommandParameter="{Binding RelativeSource={RelativeSource Self}}"Content="开启MQTT服务" />
4,ItemSource,绑定到集合元素
前端代码:
<Border Grid.Row="2" Grid.Column="3"><ListBoxx:Name="todoList"HorizontalContentAlignment="Stretch"ItemsSource="{Binding VarList}"ScrollViewer.VerticalScrollBarVisibility="Hidden"><ListBox.ItemTemplate><DataTemplate><DockPanel MaxHeight="80" LastChildFill="False"><ToggleButton DockPanel.Dock="Right" /><StackPanel><TextBlockFontSize="16"FontWeight="Bold"Text="{Binding Name}" /><TextBlockMargin="0,5"Opacity="0.5"Text="{Binding Value}" /><TextBlockMargin="0,5"Opacity="0.5"Text="{Binding Description}" /><TextBlockMargin="0,5"Opacity="0.5"Text="{Binding InsertTime}" /></StackPanel></DockPanel></DataTemplate></ListBox.ItemTemplate></ListBox></Border>
后端代码:
public ReportDataViewModel(){VarList.Add(new ActualData() { Description = "浮点数1", Name = "Float1", InsertTime = DateTime.Now, Value = CommonMethods.CurrentPLCValue["Float1"] });VarList.Add(new ActualData() { Description = "浮点数2", Name = "Float2", InsertTime = DateTime.Now, Value = CommonMethods.CurrentPLCValue["Float2"] });VarList.Add(new ActualData() { Description = "浮点数3", Name = "Float3", InsertTime = DateTime.Now, Value = CommonMethods.CurrentPLCValue["Float3"] });VarList.Add(new ActualData() { Description = "浮点数4", Name = "Float4", InsertTime = DateTime.Now, Value = CommonMethods.CurrentPLCValue["Float4"] });}private ObservableCollection<ActualData> varList = new ObservableCollection<ActualData>();public ObservableCollection<ActualData> VarList{get { return varList; }set { varList = value; }}
效果:
Prism的实例:
自动注入: prism:ViewModelLocator.AutoWireViewModel=“True”
注意视图要在Views 文件夹下,最好用View结尾(也可以不用View结尾)
ViewModel要在ViewModels文件夹下,必须用ViewModel结尾
例如:MainView 与 MainViewModel, ViewA与ViewAViewModel
设置区域:
<Windowx:Class="PrismFWDemon.Views.MainView"xmlns=""xmlns:x=""xmlns:d=""xmlns:i=""xmlns:local="clr-namespace:PrismFWDemon.Views"xmlns:materialDesign=""xmlns:mc=""xmlns:prism="/"Title="MainView"Width="1280"Height="768"prism:ViewModelLocator.AutoWireViewModel="True"Background="{DynamicResource MaterialDesignPaper}"FontFamily="微软雅黑"TextElement.FontSize="16"TextElement.FontWeight="Regular"TextElement.Foreground="{DynamicResource MaterialDesignBody}"TextOptions.TextFormattingMode="Ideal"TextOptions.TextRenderingMode="Auto"WindowStartupLocation="CenterScreen"WindowStyle="None"mc:Ignorable="d"><Grid><ContentControl prism:RegionManager.RegionName="ContentRegion" /></Grid>
</Window>
using Prism.Mvvm;
using Prism.Regions;
using PrismFWDemon.Views;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PrismFWDemon.ViewModels
{public class MainViewModel:BindableBase{private readonly IRegionManager regionManager;private string title = "Prism Application";public string Title{get { return title = "Prism Application"; }set { title = value; }}//设置了控件<ContentControl prism:RegionManager.RegionName="ContentRegion" />public MainViewModel(IRegionManager regionManager){this.regionManager = regionManager;regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));//对区域的访问//var region = regionManager.Regions["ContentRegion"];}}
}
绑定,通知,命令,订阅与发布
<UserControlx:Class="PrismFWDemon.Views.ViewA"xmlns=""xmlns:x=""xmlns:d=""xmlns:local="clr-namespace:PrismFWDemon.Views"xmlns:mc=""xmlns:prism="/"d:DesignHeight="450"d:DesignWidth="800"prism:ViewModelLocator.AutoWireViewModel="True"mc:Ignorable="d"><Grid Background="Yellow"><Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition /></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><StackPanel Orientation="Horizontal"><ButtonWidth="100"Margin="10,10,10,10"Background="Green"Command="{Binding OpenAll}"Content="点击"FontSize="28"Foreground="White" /><ButtonWidth="100"Margin="10,10,10,10"Background="Blue"Command="{Binding OpenAggregator}"Content="订阅"FontSize="28"Foreground="White" /><ButtonWidth="100"Margin="10,10,10,10"Background="Cyan"Command="{Binding SendAggregator}"Content="发布"FontSize="28"Foreground="White" /></StackPanel><StackPanel Grid.Row="1"><TextBlockHorizontalAlignment="Center"VerticalAlignment="Center"FontSize="24"Foreground="Black"Text="{Binding Title}" /></StackPanel></Grid>
</UserControl>
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using PrismFWDemon.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PrismFWDemon.ViewModels
{public class ViewAViewModel:BindableBase{private string title;private readonly IEventAggregator eventAggregator;public string Title{get { return title; }set { title = value; RaisePropertyChanged(); }}//public DelegateCommand OpenCommand//{// get// {// return new DelegateCommand(() =>// {// Title = "Prism!";// });// }//}//订阅public DelegateCommand OpenAggregator { get; private set; }//发布public DelegateCommand SendAggregator { get; private set; }public DelegateCommand OpenCommand { get; private set; }public DelegateCommand OpenCommand1 { get; private set; }public CompositeCommand OpenAll { get; private set; }//订阅消息eventAggregatorpublic ViewAViewModel(IEventAggregator eventAggregator){//this.title = "Hello";this.eventAggregator = eventAggregator;OpenCommand = new DelegateCommand(() =>{this.Title += "哈哈! \r\n";});OpenCommand1 = new DelegateCommand(() =>{this.Title += "呵呵!!! \r\n";});//订阅OpenAggregator = new DelegateCommand(() =>{this.eventAggregator.GetEvent<MessageEvent>().Subscribe(OnMessageRecived);});//发布SendAggregator = new DelegateCommand(() =>{this.eventAggregator.GetEvent<MessageEvent>().Publish("Hello World!!!!");});复合命令,一次执行2个委托//OpenAll = new CompositeCommand();//OpenAll.RegisterCommand(OpenCommand);//OpenAll.RegisterCommand(OpenCommand1);}private void OnMessageRecived(string message){Title += message + "\r\n";}}
}
using Prism.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace PrismFWDemon.Entities
{public class MessageEvent : PubSubEvent<string>{}
}
更多推荐
WPF常用的五种绑定方式
发布评论