Sök…


Syntax

  • {Binding PropertyName} motsvarar {Binding Path = PropertyName}
  • {Binding Path = SomeProperty.SomeOtherProperty.YetAnotherProperty}
  • {Binding Path = SomeListProperty [1]}

parametrar

Parameter detaljer
Väg Anger sökvägen att binda till. Om den inte är specificerad, binder den sig till DataContext.
UpdateSourceTrigger Anger när bindningskällan har sitt värde uppdaterat. Standardinställningar för LostFocus . Det mest använda värdet är PropertyChanged .
Läge Vanligtvis OneWay eller TwoWay . Om den inte är specificerad av bindningen OneWay den OneWay inte bindningsmålet begär att det ska vara TwoWay . Ett fel inträffar när TwoWay används för att binda till en läsad egenskap, t.ex. måste OneWay uttryckligen ställas in när en readonly string-egenskap TextBox.Text till TextBox.Text .
Källa Tillåter att använda en StaticResource som en bindande källa i stället för den aktuella DataContext.
RelativeSource Tillåter att använda ett annat XAML-element som en bindningskälla i stället för den aktuella DataContext.
ElementName Tillåter att använda ett namngivet XAML-element som en bindningskälla i stället för den aktuella DataContext.
FallbackValue Om bindningen misslyckas tillhandahålls detta värde till bindningsmålet.
TargetNullValue Om bindningskällvärdet är null tillhandahålls detta värde till bindningsmålet.
Omvandlare Anger omvandlaren StaticResource som används för att konvertera bindningens värde, t.ex. konvertera en booleska till en Visibility enum.
ConverterParameter Anger en valfri parameter som ska tillhandahållas till omvandlaren. Detta värde måste vara statiskt och kan inte bindas.
StringFormat Anger en formatsträng som ska användas vid visning av det bundna värdet.
Fördröjning (WPF 4.5+) Anger en försening i milliseconds för bindningen för att uppdatera BindingSource i ViewModel . Detta måste användas med Mode=TwoWay och UpdateSourceTrigger=PropertyChanged att träda i kraft.

Anmärkningar

UpdateSourceTrigger

Som standard uppdaterar WPF bindningskällan när kontrollen tappar fokus. Men om det bara finns en kontroll som kan få fokus - något som är vanligt i exempel - måste du ange UpdateSourceTrigger=PropertyChanged för att uppdateringarna ska fungera.

Du kommer att vilja använda PropertyChanged som utlösare för många tvåvägsbindningar om inte uppdatering av bindningskällan för varje tangenttryckning är kostsamt eller validering av livedata är inte önskvärt.

Att använda LostFocus har en olycklig bieffekt: genom att trycka på enter för att skicka ett formulär med en knapp märkt IsDefault uppdateras inte egenskapen som stöder din bindning, och ångrar effektivt dina ändringar. Lyckligtvis finns det några lösningar .

Observera också att till skillnad från UWP, WPF (4.5+) också har Delay i bindningar, som kanske bara räcker för vissa bindningar med lokala eller enkla mindre intelligensinställningar, som vissa TextBox valideringar.

Konvertera en boolean till synlighetsvärde

Detta exempel döljer den röda rutan (gränsen) om kryssrutan inte är markerad genom att använda en IValueConverter .

Obs: BooleanToVisibilityConverter används i exemplet nedan är en inbyggd värdekonverterare som finns i namnsområdet System.Windows.Controls.

XAML:

<Window x:Class="StackOverflowDataBindingExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="VisibleIfTrueConverter" />
    </Window.Resources>
    <StackPanel>
        <CheckBox x:Name="MyCheckBox"
                  IsChecked="True" />
        <Border Background="Red" Width="20" Height="20"
                Visibility="{Binding Path=IsChecked,ElementName=MyCheckBox, Converter={StaticResource VisibleIfTrueConverter}}" />
    </StackPanel>
</Window>

Definiera DataContext

För att arbeta med bindningar i WPF måste du definiera en DataContext . DataContext berättar för bindningar var de kan hämta sina data som standard.

<Window x:Class="StackOverflowDataBindingExample.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:StackOverflowDataBindingExample"
        xmlns:vm="clr-namespace:StackOverflowDataBindingExample.ViewModels"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <vm:HelloWorldViewModel />
    </Window.DataContext>
    ...
</Window>

Du kan också ställa in DataContext via kod bakom, men det är värt att notera att XAML IntelliSense är något picky: en starkt typad DataContext måste ställas in i XAML för IntelliSense för att föreslå egenskaper tillgängliga för bindning.

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new HelloWorldViewModel();
    }
}

Det finns ramar som hjälper dig att definiera din DataContext på ett mer flexibelt sätt (t.ex. MVVM Light har en visningsmodellokalisator som använder inversion av kontroll ), vi använder den snabba och smutsiga metoden för syftet med denna handledning.

Du kan definiera en DataContext för nästan alla visuella element i WPF. DataContext ärveras vanligtvis från förfäder i det visuella trädet om det inte uttryckligen har åsidosatts, t.ex. i ett ContentPresenter.

Implementera INotifyPropertyChanged

INotifyPropertyChanged är ett gränssnitt som används av bindningskällor (dvs. DataContext) för att låta användargränssnittet eller andra komponenter veta att en egenskap har ändrats. WPF uppdaterar automatiskt användargränssnittet för dig när händelsen PropertyChanged tas upp. Det är önskvärt att detta gränssnitt implementeras i en basklass som alla dina visningsmodeller kan ärva från.

I C # 6 är detta allt du behöver:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

Detta gör att du kan åberopa NotifyPropertyChanged på två olika sätt:

  1. NotifyPropertyChanged() , vilket kommer att höja händelsen för den setter som åberopar den, tack vare attributet CallerMemberName .
  2. NotifyPropertyChanged(nameof(SomeOtherProperty)) , vilket kommer att höja händelsen för SomeOtherProperty.

För .NET 4.5 och högre med C # 5.0 kan detta användas istället:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] string name = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

I versioner av .NET före 4.5 måste du nöja dig med egendomnamn som strängkonstanter eller som en lösning med uttryck .


Obs: Det är möjligt att binda till en egenskap hos ett "vanligt gammalt C # -objekt" (POCO) som inte implementerar INotifyPropertyChanged och observera att bindningarna fungerar bättre än förväntat. Detta är en dold funktion i .NET och bör förmodligen undvikas. Speciellt eftersom det kommer att orsaka minnesläckage när bindningens Mode inte är OneTime (se här ).

Varför uppdateras den bindande uppdateringen utan att implementera INotifyPropertyChanged?

Bindas till egendom hos ett annat namngivet element

Du kan binda till en egenskap på ett namngivet element, men det namngivna elementet måste vara i omfattning.

<StackPanel>
    <CheckBox x:Name="MyCheckBox" IsChecked="True" />
    <TextBlock Text="{Binding IsChecked, ElementName=MyCheckBox}" />
</StackPanel>

Bindas till en förfäder

Du kan binda till en egenskap hos en förfader i det visuella trädet genom att använda en RelativeSource bindning. Den närmaste kontrollen högre i det visuella trädet som har samma typ eller härrör från den typ du anger kommer att användas som bindningens källa:

<Grid Background="Blue">
    <Grid Background="Gray" Margin="10">
        <Border Background="Red" Margin="20">
            <StackPanel Background="White" Margin="20">
                <Button Margin="10" Content="Button1" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}" />
                <Button Margin="10" Content="Button2" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}}" />
            </StackPanel>
        </Border>
    </Grid>
</Grid>

I det här exemplet har knapp 1 en grå bakgrund eftersom den närmaste Grid har en grå bakgrund. Knapp2 har en vit bakgrund eftersom den närmaste förfäder som härrör från FrameworkElement är den vita StackPanel .

RelativeSource-bindande exempel

Bindning av flera värden med en MultiBinding

MultiBinding tillåter att flera värden binds till samma egenskap. I följande exempel är flera värden bundna till egenskapen Text i en textbox och formaterad med egenskapen StringFormat.

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0} {1}">
            <Binding Path="User.Forename"/>
            <Binding Path="User.Surname"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

Förutom StringFormat kan en IMultiValueConverter också användas för att konvertera värdena från bindningarna till ett värde för MultiBindings mål.

MultiBindings kan dock inte kapslas.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow