stringformat wpf data-binding binding converter

stringformat - ivalueconverter wpf



WPF: pasa el valor de un control a un convertidor para establecer el ancho en otro control (5)

Aunque sospecho que puede haber una mejor manera de resolver su problema, creo que tengo una respuesta para lo que quiere hacer. (No mencionaste de qué tipo es tu contenedor. Un StackPanel, por ejemplo, se encarga del cálculo del ancho para ti. Ver TextBox # 2 a continuación)

Primero el XAML

<Window x:Class="WpfApplication1.Window2" ... xmlns:local="clr-namespace:WpfApplication1" Title="Window2" Height="300" Width="300"> <Window.Resources> <local:WidthSansMarginConverter x:Key="widthConverter" /> </Window.Resources> <Grid> <StackPanel x:Name="stack"> <TextBlock x:Name="txtStatusMessages" Width="{Binding ElementName=stack,Path=ActualWidth, Converter={StaticResource widthConverter}}" TextWrapping="WrapWithOverflow" Background="Aquamarine" Margin="5,5,5,5"> This is a message </TextBlock> <TextBlock x:Name="txtWhatsWrongWithThis" TextWrapping="WrapWithOverflow" Background="Aquamarine" Margin="5,5,5,5"> This is another message </TextBlock> </StackPanel> </Grid> </Window>

Siguiente el convertidor. Aquí tenemos un problema ... dado que el ConvertidorParameter para los métodos Convert no puede ser un valor dinámico por algún motivo. Por lo tanto, ingresamos el Margen del cuadro de texto a través de una propiedad pública del convertidor que configuramos en el ctor de Windows. WidthSansMarginConverter.cs

public class WidthSansMarginConverter : IValueConverter { private Thickness m_Margin = new Thickness(0.0); public Thickness Margin { get { return m_Margin; } set { m_Margin = value; } } #region IValueConverter Members public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (targetType != typeof(double)) { return null; } double dParentWidth = Double.Parse(value.ToString()); double dAdjustedWidth = dParentWidth-m_Margin.Left-m_Margin.Right; return (dAdjustedWidth < 0 ? 0 : dAdjustedWidth); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } #endregion }

Window2.xaml.cs

public Window2() { InitializeComponent(); WidthSansMarginConverter obConverter = this.FindResource("widthConverter") as WidthSansMarginConverter; obConverter.Margin = txtStatusMessages.Margin; }

HTH. Gracias por el ejercicio :)

Quiero establecer el ancho de un TextBlock en función del ancho de su contenedor, menos los márgenes establecidos en el TextBlock.

Aquí está mi código

<TextBlock x:Name="txtStatusMessages" Width="{Binding ElementName=LayoutRoot,Path=ActualWidth }" TextWrapping="WrapWithOverflow" Foreground="White" Margin="5,5,5,5">This is a message </TextBlock>

Y eso funciona muy bien, excepto por el hecho de que el TextBlock es 10 unidades demasiado grande debido a que los márgenes izquierdo y derecho están establecidos en 5.

OK, entonces pensé ... Usemos un convertidor. Pero no sé cómo pasar el ancho actual del control de mi contenedor (VER ARRIBA: LayoutRoot).

Sé cómo usar convertidores, e incluso convertidores con parámetros, pero no un parámetro como ... Binding ElementName = LayoutRoot, Path = ActualWidth

Por ejemplo, no puedo hacer que esto funcione ...

Width="{Binding Converter={StaticResource PositionConverter}, ConverterParameter={Binding ElementName=LayoutRoot,Path=ActualWidth }}"

Espero haber dejado esto en claro y espero que puedas ayudar porque Google no es de ayuda para mí esta noche.

TIA!

Doug


Si su cuadro de texto es un elemento directo de LayoutRoot, simplemente configure la siguiente propiedad en su cuadro de texto

HorizontalAlignment="Stretch"



sí ... el enlace múltiple funciona para mí ... en realidad traté de enviar un elemento como un parámetro de convereter, pero no es aceptable. Es por eso que pasé el elemento como un valor para la clase de convertidor.

a continuación es mi ejemplo ...

<ListView ... > <ListView.View> <GridView> <GridViewColumn Header="xyz" > <GridViewColumn.Width> <MultiBinding Converter="{StaticResource GetWidthfromParentControl}"> <MultiBinding.Bindings> <Binding ElementName="lstNetwork" Path="ActualWidth"/> <Binding ElementName="MyGridView"/> </MultiBinding.Bindings> </MultiBinding> </GridViewColumn.Width> .... </GridViewColumn> <GridViewColumn ...> .... </GridViewColumn> </GridView> </ListView.View> </ListView>

En el cambio de tamaño de la ventana, mi primera gridviewcolumn tiene que ser redimensionada, no las otras dos columnas gridview ... pasé Actualwidth of listview y también el objeto gridview total como un elemento ... si vas al código del convertidor ...

class GetWidthfromParentControl : IMultiValueConverter { #region IMultiValueConverter Members public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { GridView view = values[1] as GridView; GridViewColumnCollection collc = view.Columns; double actualWidths = collc[1].ActualWidth + collc[2].ActualWidth; return ((double)values[0] - actualWidths ); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { return null; } #endregion }

esto funcionó para mí ... :)


se supone que debes usar el otro control como fuente, no el parámetro. El parámetro tiene que ser constante y en su caso puede ser -5.

No estoy cerca de VS en este momento, por lo que la sintaxis puede ser inexacta, sin embargo, es algo así como:

Width="{Binding ElementName=LayoutRoot, Path=ActualWidth, Converter={StaticResource PositionConverter}, ConverterParameter=-5}"

(El convertidor recibirá -5 como una cadena y deberá convertirlo en un número antes de usarlo).

Desde mi experiencia, es mejor utilizar la devolución de llamada OnXXXChanged de DependecyProperty XXX, y no vincular los controles dentro de la misma ventana / control de raíz uno a otro. Una de las razones para esto es que es posible que desee vincularlos a un elemento externo más adelante.

O alternativamente, use multibinding:

<TextBlock> <TextBlock.Width> <MultiBinding Converter="{StaticResource yourConverter}"> <MultiBinding.Bindings> <Binding /> <!-- Bind to parameter 1 here --> <Binding /> <!-- Bind to parameter 2 here --> </MultiBinding.Bindings> </MultiBinding> </TextBlock.Width> </TextBlock>

y un convertidor que convierte los dos parámetros al valor que desea.