WPF中Binding

image-20250429092124586

绑定ViewModel中的数据

添加数据上下文

方法一:在XAML中添加

<Window.DataContext>
    <local:MainWindowViewModel />
</Window.DataContext>

方法二:在界面层的cs文件中添加

this.DataContext = new MainWindowViewModel();

绑定

public string Message { get; set; } = "Hello World";
<TextBlock Text="{Binding Path=Message}" Margin="10"/>
//简写此一个参数默认是Path
<TextBlock Text="{Binding Message}" Margin="10"/>
//什么都不屑默认绑定DataContext
<TextBlock Text="{Binding}" Margin="10"/>

绑定资源字典

简单的绑定资源字典的数据

<Window.DataContext>
    <local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
    <sys:String x:Key="str">Hello, World</sys:String>
</Window.Resources>
<Grid>
    <TextBlock Text="{Binding Source={StaticResource str}}" Margin="10"/>
    //简写
        <TextBlock Text="{staticResource str}" Margin="10"/>
        //绑定动态资源只能这样简写,写完整会报错
        <TextBlock Text="{DynamicResource str}" Margin="10"/>
</Grid>

绑定cs文件中资源字典的数据

先定义一个类

class MyResourece
{
    public string Message { get; } = "Public Property";
    public static string StaticString = "Static String";
    public const string ConstString = "Const String";
}

把类读取到资源字典

<Window.Resources>
    <local:MyResourece x:Key="mysource" />
</Window.Resources>

对于静态,常量,enum,都得用x:Staic来访问,普通的资源可以用StaticResource

<TextBlock Text="{Binding Source={StaticResource mysource},Path=Message}"/>
//静态和常量得用x:Static访问
<TextBlock Grid.Row="1" Text="{Binding Source={x:Static local:MyResourece.ConstString}}" />
<TextBlock Grid.Row="2" Text="{Binding Source={x:Static local:MyResourece.StaticString}}" />

绑定控件

ElementName

<StackPanel>
    <TextBox x:Name="txt" />
    <TextBlock Text="{Binding ElementName=txt, Path=Text}" />
</StackPanel>

x:Reference

当ElementName失效时可以用x:Reference,这是通用什么情况下都可以用

TextBlock Text="{Binding Source={x:Reference Name=txt},Path=Text}" />

RelativeSource

<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window},Path=Top}" />

我想读取到tag1的写法,当有多个相同的属性可以用AncestorLevel=3,标识找到父级第三个Grid

<Grid Tag="tag1">
    <Grid Tag="tag2">
        <Grid Tag="tag3">
            <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Grid,AncestorLevel=3},Path=Tag}" />
        </Grid>
    </Grid>
</Grid>

用ReletiveSource绑定同级别控件

<StackPanel>
    <TextBox />
    <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=StackPanel},Path=Children[0].Text}" />
</StackPanel>

绑定自己的写法四种写法

<TextBlock Text="{Binding RelativeSource={RelativeSource Mode=Self},Path=ActualWidth}" />
<TextBlock Text="{Binding RelativeSource={RelativeSource Self},Path=ActualWidth}" />
<TextBlock Text="{Binding RelativeSource={x:Static RelativeSource.Self},Path=ActualWidth}" />
<TextBlock Text="{Binding RelativeSource={RelativeSource 2},Path=ActualWidth}" />

绑定模板的属性,两种先给发等价

<StackPanel>
    <Label Padding="10">
        <Label.Template>
            <ControlTemplate TargetType="Label">
                <Border Padding="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=Padding}">
                    <ContentPresenter />
                </Border>
            </ControlTemplate>
        </Label.Template>
    </Label>
</StackPanel>
<StackPanel>
    <Label Padding="10">
        <Label.Template>
            <ControlTemplate TargetType="Label">
                <Border>
                    <ContentPresenter Margin="{TemplateBinding Padding}" />
                </Border>
            </ControlTemplate>
        </Label.Template>
    </Label>
</StackPanel>

StringFormat

StringFormat可以指定格式,:F3表示小数点后三位小数

<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=Top,StringFormat='Top:{0:F3}'}" />

MultiBinding

<StackPanel>
    <TextBlock>
        <TextBlock.Text>
            <MultiBinding StringFormat="Pos:{0},{1}">
                <Binding Path="Top"
                         RelativeSource="{RelativeSource AncestorType=Window}" />
                <Binding Path="Left"
                         RelativeSource="{RelativeSource AncestorType=Window}" />

            </MultiBinding>
        </TextBlock.Text>
    </TextBlock>
</StackPanel>

有Content属性的控件,可以用ContentStringFormat

<StackPanel>
    <Label Content="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=Top}"
           ContentStringFormat="Top:{0:F3}" />
</StackPanel>

FallbackValue和TargetNullValue

FallbackValue在没有绑定成功时优先显示

TargetNullValue在绑定的值为空时优先显示

<Label Content="{Binding Message,FallbackValue=dasdaa,TargetNullValue=asdasd}"/>

对比

RelativeSource、ElementName、x:Reference中前两者依赖对象树寻找关系,x:Reference可以从文档搜索,前两者绑定失效可以用x:Reference

x:Reference的缺陷,无法绑定自己的父级

BindingProxy

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
<Window.Resources>
    <local:MyResourece x:Key="mysource" />
    <local:BindingProxy x:Key="mybtn"
                        Data="{Binding ElementName=btn}" />
</Window.Resources>
<StackPanel>
    <Button Name="btn"
            Content="Click Me">
        <Button.ToolTip>
            <ToolTip>
                <StackPanel>
                    <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Button},Path=Content}" />
                    <TextBlock Text="{Binding Source={StaticResource mybtn},Path=Data.Content}" />
                </StackPanel>
               
            </ToolTip>
        </Button.ToolTip>
    </Button>
</StackPanel>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值