Startsidan  ▸  Texter  ▸  Teknikblogg

Anders Hesselbom

Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.

Lathund XAML: Reflektera förändringar vid data binding

2015-11-11

En enkel databindning (alltså databindning av en post) åstadkommer man i WPF genom att tilldela ett objekt till DataContext för containern av kontrollerna som ska bindas. Här har jag tilldelat ett namn till Grid-elementet som ligger på huvudfönstret från början, och placerat en TextBox däri som jag binder till propertyn FirstName.

<Grid Name="theGrid">
   <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="283,103,0,0"
   TextWrapping="Wrap" VerticalAlignment="Top" Width="120"
   Text="{Binding FirstName}" />
</Grid>

Givet att programmet har tillgång till klassen Employee (förra exemplet) och att fönstret har en medlemsvariabeln (emp) av den typen, så kan vi i t.ex. Initialized-eventet göra tilldelningen till DataContext.

this.emp = new Employee() { FirstName = "Sven" };
this.theGrid.DataContext = this.emp;

Om vi under resans gång försöker läsa av propertyn FirstName, så kommer eventuella ändringar som användaren gjort i det bundna textfältet att ha reflekterats tillbaka till propertyn. Om vi är intresserade av att validera inmatat data behöver vi kunna registrera valideringsregler från programmet på kontrollens container. I mitt lilla exempelprojekt heter root-namnrymden WpfApplication1.

<Grid Name="theGrid" xmlns:val="clr-namespace:WpfApplication1">

Klassen som sköter valideringen måste ärva från klassen ValidationRule. Notera att jag kallar valideringsklassen för NameValidationRule.

class NameValidationRule : System.Windows.Controls.ValidationRule
{
   public int MinLength { get; set; }
   public string ErrorMessage { get; set; }

   public override ValidationResult Validate(object value, CultureInfo cultureInfo)
   {
      var s = (value as string == null ? "" : value as string).Trim();
      if (s.Length < this.MinLength)
         return new ValidationResult(false, this.ErrorMessage);
      return new ValidationResult(true, null);
   }
}

Därefter använder jag den XML-namnrymd jag tidigare registrerade (val) när jag registrerar klassen NameValidationRule.

<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="283,103,0,0"
   TextWrapping="Wrap" VerticalAlignment="Top" Width="120">
   <Binding Path="FirstName">
      <Binding.ValidationRules>
         <val:NameValidationRule MinLength="2" ErrorMessage="Fel!" />
      </Binding.ValidationRules>
   </Binding>
</TextBox>

Slutligen, om jag vill använda kod för att detektera att inmatningen inte validerar så finns det flera metoder. Den enklaste är att använda kontrollens funktion GetBindingExpression som ger ett objekt som helt enkelt har en property som heter HasError.

var binding = textBox.GetBindingExpression(TextBox.TextProperty);
if (binding.HasError)
   return;

Detta kan göras t.ex. när användaren klickar OK.

Categories: General

Leave a Reply

Your email address will not be published. Required fields are marked *



En kopp kaffe!

Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!

Bjud på en kopp kaffe!

Om...

Kontaktuppgifter, med mera, finns här.

Följ mig

Twitter Instagram
GitHub RSS

Public Service

Folkbildning om public service.

Hem   |   linktr.ee/hesselbom   |   winsoft.se   |   80tal.se   |   Filmtips