Windows 8 Store App - Binding wartości FontSize (XAML) z kodem w C#

0

Witam wszystkich!

Mam taki mały problem, a mianowicie niezbyt rozumiem wiązanie (Binding) w XAML i C#. Potrzebuję powiązać rozmiar czcionki z kodem w programie i nie mam pojęcia jak tego dokonać. Przeglądałem już mnóstwo tematów i sam męczę się z tym od dwóch dni, aż w końcu brakło mi pomysłów, więc piszę tutaj. Chciałbym, aby rozmiar czcionki w przycisku automatycznie mi się dostosowywał do szerokości, aby nie było tzw. ucięcia, przy jednoczesnym braku zmian w wartości marginesu od kolumny i wiersza.

Mój kod XAML dla templatki przycisku:

<Style x:Key="ButtonStyleNormal" TargetType="Button">
	<Setter Property="Background" Value="{ThemeResource ButtonBackgroundThemeBrush}"/>
	<Setter Property="Foreground" Value="{ThemeResource ButtonForegroundThemeBrush}"/>
	<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderThemeBrush}"/>
	<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
	<Setter Property="Padding" Value="12,4,12,4"/>
	<Setter Property="HorizontalAlignment" Value="Left"/>
	<Setter Property="VerticalAlignment" Value="Center"/>
	<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
	<Setter Property="FontWeight" Value="SemiBold"/>
	<!--<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>-->
	<Setter Property="FontSize" Value="64"/> <!-- TUTAJ CHCIAŁBYM ZASTOSOWAĆ POWIĄZANIE -->
	<Setter Property="Template">
		*
		*
		*
</Style>

I powiedzmy, że chciałbym go powiązać z tą metodą:

private void changeFontSize(object sender, EventArgs e)
{
	double size = 64 * ActualWidth / 1280;
	button.FontSize = size;
}

Z góry dziękuję za w miarę szybką pomoc w pojęciu Bindingu i przy rozwiązaniu problemu. :)

Pozdrawiam!

0

Podstawowe pytanie do czego chcesz robić binding w stylu?

0

Napisałem to komentarzem. Do value w FontSize jeśli o to pytasz :)

0

Po pierwsze nie bindujemy do metody tylko właściwości

        public double changeFontSize
        {
            get{  return 64 * ActualWidth / 1280;}             
        }
 
<Setter Property="FontSize" Value="{Binding changeFontSize}"/>  

Powyższy kod wywoła się jednak jeden raz w momencie przypisywania wartości a Ty chciałbyś żeby za każdym razem, gdy zmieniana jest właściwość ActualWidth. Wystarczy w tym celu zrobić

 <Setter Property="FontSize" Value="{Binding ActualWidth, converter={StaticResource konwerter}}"/> 

I zastosować konwerter, w którym w metodzie Convert wstawisz to 64 * ActualWidth / 1280, ActualWidth będzie w metodzie wywołania jako value. ActualWidth jest zapewne zwykłą właściwością, więc musi informować o swoich zmianach implementując Interfejs INotifyPropertyChanged, chyba, że jest typu Dependency Property wówczas jest już to zapewnione.

0

Witam, próbuję zastosować się do Twoich wskazówek i stworzyłem konwerter fontConverter. Niestety przy przypisaniu tego w sposób:

<Setter Property="FontSize" Value="{Binding ActualWidth, Converter=StaticResource fontConverter}"/>

I użyciu metody Convert z fontConverter

public class fontConverter : IValueConverter
{
	public object Convert(object value, Type targetType, object parameter, string language)
	{
		return 64 * (double)value / 1280;
	}

	public object ConvertBack(object value, Type targetType, object parameter, string language)
	{
		throw new NotImplementedException();
	}
}

Pod Value="{Binding wskazuje mi błąd: The TypeConverter for "IValueConverter" does not support converting from a string.

Niestety póki to dla mnie jeszcze czarna magia ( pierwsza aplikacja Win8 ) dlatego przepraszam za możliwe niepojęcie tego co chciałem przekazać w odpowiedni sposób ^^

0

Szukaj w Internecie, pierwszy wynik
http://codeblog.vurdalakov.net/2013/10/typeconverter-for-ivalueconverter-does-not-support-converting-from-a-string.html

 <Setter Property="FontSize" Value="{Binding ActualWidth, Converter={StaticResource fontConverter}}"/>

zabrakło nawiasów klamrowych.

0

Niestety zanim przesłałem poprzednią wiadomość próbowałem już rozwiązać to w ten sposób. W tym przypadku ( kiedy zastosuje się do tych nawiasów klamrowych ) podkreśla całość:

Value="{Binding ActualWidth, Converter={StaticResource fontConverter}}"

Informacja dla podkreślenia: The resource "fontConverter" could not be resolved.

0

Utworzyłeś obiekt konwertera w zasobach?
http://wpftutorial.net/ValueConverters.html

0

Dobra, błędów nie ma, ale niestety rozmiar czcionki ustawia się właściwie minimalny, czyli tak jakby to w ogóle tego nie obliczało. To jest podsumowanie kodu, który obecnie mam:

C#:

public class fontConverter : IValueConverter
{
	public object Convert(object value, Type targetType, object parameter, string language)
	{
		return 64 * (double)value / 1280;
	}
	public object ConvertBack(object value, Type targetType, object parameter, string language)
	{
		throw new NotImplementedException();
	}
}

XAML:

<Page Name="Step2"
	...
	xmlns:local="using:Organizer" <!-- namespace w którym jest klasa do konwersji -->
	...
	x:Class="Organizer.StepTwo"
	...>
	<Page.Resources>
		<local:fontConverter x:Key="converter" />
		...
		<Style x:Key="ButtonStyleNormal" TargetType="Button">
			...
			<Setter Property="FontSize" Value="{Binding ActualWidth, Converter={StaticResource converter}}"/>
			...
		</style>
	</Page.Resources>
	...

Nie wiem właściwie dlaczego ta czcionka się nie zmienia. Teoretycznie powinno już wchodzić do funkcji i zwracać

return 64 * (double)value / 1280;

ale tego nie robi. ;/

0

Wpisz

    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return 64 * (double)value / 1280;
        Debug.WriteLine("now");
    } 

Wówczas w oknie output będzie wynik i będziesz wiedział ile razy została uruchomiona i czy wtedy kiedy zmienia się właściwość ActualWidth. Przypuszczam, że tylko raz na samym początku a potem nie. Wiązanie zostało ustawione z właściwością ActualWidth

  Value="{Binding ActualWidth,

aby przy każdej jej zmianie następowało uruchomienie konwertera, metody Convert i ustawienie czcionki. W tym celu właściwość ActualWidth musi informować o swoich zmianach wszystkie elementy, które ustawią z nią wiązanie(bindowanie). W tym celu klasa zawierającą tą właściwość musi implementować interfejs INotifyPropertyChanged

http://codepronet.blogspot.com/2009/08/implementing-inotifypropertychanged.html

0

Popraw:

<Setter Property="FontSize" Value="{Binding ActualWidth, Converter={StaticResource converter}}"/>

na

<Setter Property="FontSize"
                 Value="{Binding Path=ActualWidth, RelativeSource={RelativeSource Self}, Converter={StaticResource converter}}" />

I powinno zadziałać. ;)

0

Zastosowałem się do obu wskazówek i niestety brak zmian. W output widnieje błąd: Error: BindingExpression path error: 'ActualWidth' property not found on 'Windows.UI.Xaml.Setter'. BindingExpression: Path='ActualWidth' DataItem='Windows.UI.Xaml.Setter'; target element is 'Windows.UI.Xaml.Setter' (Name='null'); target property is 'Value' (type 'Object')

0

Zrób tak jak Diggy napisał

<Setter Property="FontSize" Value="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={StaticResource konwerter}}"/> 

Myślałem, że ActualWidth rozumiesz jako zwykłą właściwość .NET, która nie informuje o zmianach a Ty miałeś na myśli właściwość obiektu Button typu Dependency Property. Sprawdziłem u mnie działa.

0

Właśnie problem w tym, że stosując się do kodu, który podesłał Dibby, mam ten błąd w output, który wypisałem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1