WP中系统没有像WPF中直接支持MultiBinding,可以通过以下代码实现

五个类

    public class BindingCollection : Collection<BindingBase>
{
// Fields
private readonly BindingCollectionChangedCallback _collectionChangedCallback; // Methods
//internal BindingCollection(BindingCollectionChangedCallback callback)
//{
// _collectionChangedCallback = callback;
//} protected override void ClearItems()
{
base.ClearItems();
OnBindingCollectionChanged();
} protected override void InsertItem(int index, BindingBase item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
ValidateItem(item);
base.InsertItem(index, item);
OnBindingCollectionChanged();
} private void OnBindingCollectionChanged()
{
if (_collectionChangedCallback != null)
{
_collectionChangedCallback();
}
} protected override void RemoveItem(int index)
{
base.RemoveItem(index);
OnBindingCollectionChanged();
} protected override void SetItem(int index, BindingBase item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
ValidateItem(item);
base.SetItem(index, item);
OnBindingCollectionChanged();
} private static void ValidateItem(BindingBase binding)
{
if (!(binding is Binding))
{
throw new NotSupportedException("BindingCollectionContainsNonBinding");
}
}
}

BindingCollection

    /// <summary>
/// A simple element with a single Value property, used as a 'slave'
/// for a Binding.
/// </summary>
public class BindingSlave : FrameworkElement, INotifyPropertyChanged
{
#region Value public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(object), typeof(BindingSlave),
new PropertyMetadata(null, OnValueChanged)); public object Value
{
get { return GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
} private static void OnValueChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
BindingSlave slave = depObj as BindingSlave;
Debug.Assert(slave != null);
slave.OnPropertyChanged("Value");
} #endregion #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
} #endregion }

BindingSlave

    /// <summary>
/// Provides a mechanism for attaching a MultiBinding to an element
/// </summary>
public class BindingUtil
{
#region DataContextPiggyBack attached property /// <summary>
/// DataContextPiggyBack Attached Dependency Property, used as a mechanism for exposing
/// DataContext changed events
/// </summary>
public static readonly DependencyProperty DataContextPiggyBackProperty =
DependencyProperty.RegisterAttached("DataContextPiggyBack", typeof(object), typeof(BindingUtil),
new PropertyMetadata(null, new PropertyChangedCallback(OnDataContextPiggyBackChanged))); public static object GetDataContextPiggyBack(DependencyObject d)
{
return (object)d.GetValue(DataContextPiggyBackProperty);
} public static void SetDataContextPiggyBack(DependencyObject d, object value)
{
d.SetValue(DataContextPiggyBackProperty, value);
} /// <summary>
/// Handles changes to the DataContextPiggyBack property.
/// </summary>
private static void OnDataContextPiggyBackChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement targetElement = d as FrameworkElement; // whenever the targeElement DataContext is changed, copy the updated property
// value to our MultiBinding.
MultiBindings relay = GetMultiBindings(targetElement);
relay.SetDataContext(targetElement.DataContext);
} #endregion #region MultiBindings attached property public static MultiBindings GetMultiBindings(DependencyObject obj)
{
return (MultiBindings)obj.GetValue(MultiBindingsProperty);
} public static void SetMultiBindings(DependencyObject obj, MultiBindings value)
{
obj.SetValue(MultiBindingsProperty, value);
} public static readonly DependencyProperty MultiBindingsProperty =
DependencyProperty.RegisterAttached("MultiBindings",
typeof(MultiBindings), typeof(BindingUtil), new PropertyMetadata(null, OnMultiBindingsChanged)); /// <summary>
/// Invoked when the MultiBinding property is set on a framework element
/// </summary>
private static void OnMultiBindingsChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
FrameworkElement targetElement = depObj as FrameworkElement; // bind the target elements DataContext, to our DataContextPiggyBack property
// this allows us to get property changed events when the targetElement
// DataContext changes
targetElement.SetBinding(DataContextPiggyBackProperty, new Binding()); MultiBindings bindings = GetMultiBindings(targetElement); bindings.Initialize(targetElement);
} #endregion }

BindingUtil

    /// <summary>
/// see: http://msdn.microsoft.com/en-us/library/system.windows.data.imultivalueconverter.aspx
/// </summary>
public interface IMultiValueConverter
{
object Convert(object[] values, Type targetType, object parameter, CultureInfo culture); object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture);
}

IMultiValueConverter

    /// <summary>
/// Allows multiple bindings to a single property.
/// </summary>
[ContentProperty("Bindings")]
public class MultiBinding : Panel, INotifyPropertyChanged
{
#region ConvertedValue dependency property public static readonly DependencyProperty ConvertedValueProperty =
DependencyProperty.Register("ConvertedValue", typeof(object), typeof(MultiBinding),
new PropertyMetadata(null, OnConvertedValue)); /// <summary>
/// This dependency property is set to the resulting output of the
/// associated Converter.
/// </summary>
public object ConvertedValue
{
get { return GetValue(ConvertedValueProperty); }
set { SetValue(ConvertedValueProperty, value); }
} private static void OnConvertedValue(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
MultiBinding relay = depObj as MultiBinding;
Debug.Assert(relay != null);
relay.OnPropertyChanged("ConvertedValue");
} #endregion #region CLR properties /// <summary>
/// The target property on the element which this MultiBinding is assocaited with.
/// </summary>
public string TargetProperty { get; set; } /// <summary>
/// The Converter which is invoked to compute the result of the multiple bindings
/// </summary>
public IMultiValueConverter Converter { get; set; } /// <summary>
/// The configuration parameter supplied to the converter
/// </summary>
public object ConverterParameter { get; set; } /// <summary>
/// The bindings, the result of which are supplied to the converter.
/// </summary>
public BindingCollection Bindings { get; set; } #endregion public MultiBinding()
{
Bindings = new BindingCollection();
} /// <summary>
/// Invoked when any of the BindingSlave's Value property changes.
/// </summary>
private void SlavePropertyChanged(object sender, PropertyChangedEventArgs e)
{
UpdateConvertedValue();
} /// <summary>
/// Uses the Converter to update the ConvertedValue in order to reflect
/// the current state of the bindings.
/// </summary>
private void UpdateConvertedValue()
{
List<object> values = new List<object>();
foreach (BindingSlave slave in Children)
{
values.Add(slave.Value);
}
ConvertedValue = Converter.Convert(values.ToArray(), typeof(object), ConverterParameter, CultureInfo.CurrentCulture);
} /// <summary>
/// Creates a BindingSlave for each Binding and binds the Value
/// accordingly.
/// </summary>
internal void Initialise()
{
Children.Clear();
foreach (Binding binding in Bindings)
{
BindingSlave slave = new BindingSlave();
slave.SetBinding(BindingSlave.ValueProperty, binding);
slave.PropertyChanged += SlavePropertyChanged;
Children.Add(slave);
}
} #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
} #endregion
}

MultiBinding

    [ContentProperty("Bindings")]
public class MultiBindings : FrameworkElement
{
private FrameworkElement _targetElement; public ObservableCollection<MultiBinding> Bindings { get; set; } public MultiBindings()
{
Bindings = new ObservableCollection<MultiBinding>();
}
#if !SILVERLIGHT
void Loaded(object sender, RoutedEventArgs e)
{
_targetElement.Loaded -= Loaded;
foreach (MultiBinding binding in Bindings)
{
FieldInfo field = _targetElement.GetType().GetField(binding.TargetProperty + "Property", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
if (field == null) continue; System.Windows.Data.MultiBinding newBinding = new System.Windows.Data.MultiBinding
{
Converter = binding.Converter,
ConverterParameter = binding.ConverterParameter
};
foreach (BindingBase bindingBase in binding.Bindings)
{
newBinding.Bindings.Add(bindingBase);
} DependencyProperty dp = (DependencyProperty)field.GetValue(_targetElement); BindingOperations.SetBinding(_targetElement, dp, newBinding);
} }
#endif public void SetDataContext(object dataContext)
{
foreach (MultiBinding relay in Bindings)
{
relay.DataContext = dataContext;
}
} public void Initialize(FrameworkElement targetElement)
{
_targetElement = targetElement;
#if !SILVERLIGHT
_targetElement.Loaded += Loaded;
#else
const BindingFlags DpFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy; foreach (MultiBinding relay in Bindings)
{
relay.Initialise(); // find the target dependency property
Type targetType = null;
string targetProperty = null; // assume it is an attached property if the dot syntax is used.
if (relay.TargetProperty.Contains("."))
{
// split to find the type and property name
string[] parts = relay.TargetProperty.Split('.');
targetType = Type.GetType("System.Windows.Controls." + parts[] +
", System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e");
targetProperty = parts[];
}
else
{
targetType = targetElement.GetType();
targetProperty = relay.TargetProperty;
} FieldInfo[] sourceFields = targetType.GetFields(DpFlags);
FieldInfo targetDependencyPropertyField =
sourceFields.First(i => i.Name == targetProperty + "Property");
DependencyProperty targetDependencyProperty =
targetDependencyPropertyField.GetValue(null) as DependencyProperty; // bind the ConvertedValue of our MultiBinding instance to the target property
// of our targetElement
Binding binding = new Binding("ConvertedValue") { Source = relay };
targetElement.SetBinding(targetDependencyProperty, binding);
}
#endif
}
}

MultiBindings

1、定义两个Converter

    //用于多个bool转化为Visibility
public class VisibilityConverter : IMultiValueConverter
{
#region IMultiValueConverter Members public object Convert(object[] values, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
if (values.Any(value => !(bool) value))
{
return Visibility.Collapsed;
}
return Visibility.Visible;
} public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
} #endregion
} //多个文本转换
public class TextConverter : IMultiValueConverter
{
#region IMultiValueConverter Members public object Convert(object[] values, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
return string.Join(", ", values);
} public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
} #endregion
}

Converter

2、在Xaml绑定

<phone:PhoneApplicationPage
x:Class="Bomo.Test.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:multiBindingExtend="clr-namespace:Bomo.Test.MultiBindingExtend"
xmlns:test="clr-namespace:Bomo.Test"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True"
DataContext="{Binding RelativeSource={RelativeSource Self}}"> <phone:PhoneApplicationPage.Resources>
<test:VisibilityConverter x:Key="VisibilityConverter"></test:VisibilityConverter>
<test:TextConverter x:Key="TextConverter"></test:TextConverter>
</phone:PhoneApplicationPage.Resources> <!--LayoutRoot 是包含所有页面内容的根网格-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="多路绑定" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock Text="MultiBinding" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions> <StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<TextBlock >如果两个开关都打开,方块变红色</TextBlock>
<Grid>
<Rectangle Width="300" Height="30" Fill="#eee" Margin="10"></Rectangle>
<Rectangle Width="300" Height="30" Fill="Red" Margin="10" >
<multiBindingExtend:BindingUtil.MultiBindings>
<multiBindingExtend:MultiBindings>
<multiBindingExtend:MultiBinding TargetProperty="Visibility" Converter="{StaticResource VisibilityConverter}">
<multiBindingExtend:MultiBinding.Bindings>
<multiBindingExtend:BindingCollection>
<Binding Path="Toggle1IsChecked"/>
<Binding Path="Toggle2IsChecked"/>
</multiBindingExtend:BindingCollection>
</multiBindingExtend:MultiBinding.Bindings>
</multiBindingExtend:MultiBinding>
</multiBindingExtend:MultiBindings>
</multiBindingExtend:BindingUtil.MultiBindings>
</Rectangle> </Grid>
</StackPanel>
<ToggleButton Grid.Row="2" Grid.Column="0" IsChecked="{Binding Toggle1IsChecked, Mode=TwoWay}">开关1</ToggleButton>
<ToggleButton Grid.Row="2" Grid.Column="1" IsChecked="{Binding Toggle2IsChecked, Mode=TwoWay}">开关2</ToggleButton> </Grid> <Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">下面文本绑定了两个文本框的内容</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Foreground="{StaticResource PhoneAccentBrush}">
<multiBindingExtend:BindingUtil.MultiBindings>
<multiBindingExtend:MultiBindings>
<multiBindingExtend:MultiBinding TargetProperty="Text" Converter="{StaticResource TextConverter}">
<multiBindingExtend:MultiBinding.Bindings>
<multiBindingExtend:BindingCollection>
<Binding Path="Text1"/>
<Binding Path="Text2"/>
</multiBindingExtend:BindingCollection>
</multiBindingExtend:MultiBinding.Bindings>
</multiBindingExtend:MultiBinding>
</multiBindingExtend:MultiBindings>
</multiBindingExtend:BindingUtil.MultiBindings>
</TextBlock> <TextBox Grid.Row="2" Grid.Column="0" Text="{Binding Text1, Mode=TwoWay}"></TextBox>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Text2, Mode=TwoWay}"></TextBox>
</Grid> </Grid> </phone:PhoneApplicationPage>

MainPage.xaml

3、后台绑定

    public partial class MainPage : INotifyPropertyChanged
{
// 构造函数
public MainPage()
{
InitializeComponent();
} #region Toggle1IsChecked /// <summary>
/// The <see cref="Toggle1IsChecked" /> property's name.
/// </summary>
public const string Toggle1IsCheckedPropertyName = "Toggle1IsChecked"; private bool _toggle1IsChecked = false; /// <summary>
/// Sets and gets the Toggle1IsChecked property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public bool Toggle1IsChecked
{
get
{
return _toggle1IsChecked;
} set
{
if (_toggle1IsChecked == value)
{
return;
} _toggle1IsChecked = value;
RaisePropertyChanged(Toggle1IsCheckedPropertyName);
}
} #endregion #region Toggle2IsChecked /// <summary>
/// The <see cref="Toggle2IsChecked" /> property's name.
/// </summary>
public const string Toggle2IsCheckedPropertyName = "Toggle2IsChecked"; private bool _toggle2IsChecked = false; /// <summary>
/// Sets and gets the Toggle2IsChecked property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public bool Toggle2IsChecked
{
get
{
return _toggle2IsChecked;
} set
{
if (_toggle2IsChecked == value)
{
return;
} _toggle2IsChecked = value;
RaisePropertyChanged(Toggle2IsCheckedPropertyName);
}
} #endregion #region Text1
/// <summary>
/// The <see cref="Text1" /> property's name.
/// </summary>
public const string Text1PropertyName = "Text1"; private string _text1 = string.Empty; /// <summary>
/// Sets and gets the Text1 property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string Text1
{
get
{
return _text1;
} set
{
if (_text1 == value)
{
return;
} _text1 = value;
RaisePropertyChanged(Text1PropertyName);
}
} #endregion #region Text2 /// <summary>
/// The <see cref="Text2" /> property's name.
/// </summary>
public const string Text2PropertyName = "Text2"; private string _text2 = string.Empty; /// <summary>
/// Sets and gets the Text2 property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string Text2
{
get
{
return _text2;
} set
{
if (_text2 == value)
{
return;
} _text2 = value;
RaisePropertyChanged(Text2PropertyName);
}
} #endregion #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
} #endregion
}

MainPage.xaml.cs

这里只支持到属性的绑定,不支持到UIElement的绑定

本文引用自:http://blog.csdn.net/huangliangjie/article/details/6734099

【WP8】MultiBinding的更多相关文章

  1. 【WP8】WebBrowser相关

    2014年09月02日更新 今天用了一下WebBrowser,在使用过程中也遇到了一些问题,在这里做一下记录 虽然WebBrowser比较重,会比较影响性能(除非一定要用到它,否则尽量少用),但有时候 ...

  2. 【WP8】线程安全的StorageHelper

    14-08-29 12:32更新:修复StorageHelper部分bug WP8以后提供了StorageFile的方式访问文件,StorageFile对文件的操作只提供了异步的支持,包括WP8.1 ...

  3. 【WP8】让TextBox文本支持滑动(Scroll)

    通过修改样式让TextBox支持文本滑动 在Silverlight上,TextBox是有文本滚动的功能的,当TextBox的文本过长时,可以进行拖动的,TextBox使用 VerticalScroll ...

  4. 【WP8】自定义配置存储类

    之前在WP7升级到WP8的时候遇到配置不兼容的问题 情景:之前只有一个WP7版本,现在需要发布WP8版本,让用户可以从原来的WP7版本升级到WP8版本 一般情况下从WP7升级到WP8没什么问题 但是在 ...

  5. 【WP8】ResourceDictionary

    WP8中引用资源字典 当我们定义的样式太多的时候,我们可以把样式分别定义在不同的文件中,然后通过 MergedDictionaries 应用到其他资源字典中,看下面Demo 我们可以把样式定义在多个文 ...

  6. 【WP8】LoopingSelector

    WP8的WindowsPhoneToolkit工具包中有一个 LoopingSelector 可以想选择日期或时间一样进行选择 1.首先当然是引用WindowsPhoneToolkit 在Nuget控 ...

  7. 【WP8】为Webbrowser添加ScrollBar

    在WP8中,控件WebBrowser没有提供对滚动条的支持,而在内置的IE中,却可以显示出滚动条(微软这是在坑我们吗),但如果在客户端使用Webbrowser的话,自己构造ScrollBar来显示 通 ...

  8. 【WP8】Uri关联启动第三方App

    在WP8中支持启动第三方应用程序,比如在App1中可以打开App2,你可以在你的应用程序中直接打开QQ,也可以让其他开发者调用你的APP,例如:软件盒子 下面演示被调用方和调用方的使用方法,新建两个项 ...

  9. 【WP8】WP8调用官方API使用LED灯

    在WP7中没有相关的API可以直接使用摄像头的LED等,只能通过录像时打开LED等来使用,在WP8中添加了相关的调用接口,可以方便的使用LED灯,并且支持后台,废话不多说,直接上代码 1.在 WMAp ...

随机推荐

  1. Delphi调用JAVA的WebService上传XML文件(XE10.2+WIN764)

    相关资料:1.http://blog.csdn.net/luojianfeng/article/details/512198902.http://blog.csdn.net/avsuper/artic ...

  2. strace命令学习

    跟踪一个php程序的运行: strace -s 1000 -f -o test.log php test.php 对于守护进程(后台一直跑的进程) php test.php &   得到它的P ...

  3. MyBatis 批量插入获取自增 id 问题解决

    问题: 通过 MyBatis 进行批量插入时,如果我们想获取插入对象所对应的主键 id,做法是直接在 <insert> 标签中直接加入 useGeneratedKeys.keyProper ...

  4. 调整Intellij IDEA内存

    最近IDEA真是卡的要死,下面

  5. Go Revel - Session / Flash(会话与flash)

    ##Session / Flash 作用域 revel提供了两种cookies存储机制: // 一个加密签过的cookie (限制为4kb). // 限制: Key 中不能有冒号 type Sessi ...

  6. 【基础练习】【区间DP】codevs1090 加分二叉树题解

    2003 NOIP TG 题目描写叙述 Description 设一个n个节点的二叉树tree的中序遍历为(l,2,3,-,n),当中数字1,2,3,-,n为节点编号.每一个节点都有一个分数(均为正整 ...

  7. 自适应瀑布型布局(手机,PC全兼容)

    有个瀑布型的布局需求,于是找了下,网上大部分用jquery控件,界面太复杂,看起来很笨重,我需求比较简单,于是只能自己写 其实原理就是用cs 去控制,那么我们只需要把对应的界面去规划就行了,比如,我一 ...

  8. tabs 标签样式

    http://www.jq22.com/jquery-info17973 http://www.jq22.com/demo/elementTab201801262311/ 插件描述:基于element ...

  9. Spring Cloud Config 自动刷新所有节点

    全局刷新 详细参考:<Sprin Cloud 与 Docker 微服务架构实战>p160-9.9.2节 1.使用Spring Cloud Config 客户端时,可以使用 /refresh ...

  10. C程序模拟实现银行家算法

    C程序模拟实现银行家算法 上周又做操作系统实验,题目是用程序模拟实现银行家算法,写了半天还真有点晕,主要是因为想尽可能符合课本上的描述,所以写出来的程序就比较恶心了,好了,银行家算法就不多说了,不了解 ...