2008-11-23 29 views
11

我想根據其容器的寬度減去TextBlock上設置的邊距來設置TextBlock的寬度。WPF - 將一個控件的值傳遞給一個Converter來設置另一個控件的寬度

這裏是我的代碼

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

而且除了事實的TextBlock爲10個單位太大,由於左,右頁邊距bbeing設置爲5

OK,工程很大,所以我想......讓我們使用一個轉換器。但我不知道如何傳遞我的容器控件的ActualWidth(見上圖:LayoutRoot)。

我知道如何使用轉換器,甚至轉換器,參數,只是沒有一個參數像...綁定的ElementName = LayoutRoot,路徑= ActualWidth的

例如,我無法使這項工作...

我希望我說得很清楚,希望你能幫上忙,因爲Google今晚對我毫無幫助。

TIA!

Doug

回答

11

你應該使用其他控件作爲源,而不是參數。 參數必須是常數,在你的情況下可以是-5。

我不VS附近此刻所以,語法,也許不準確的,但是,它是這樣的:

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

(轉換器將收到-5作爲字符串,將不得不把它轉換成)

根據我的經驗,最好使用DependecyProperty XXX的OnXXXChanged回調,並且不要將同一窗口/根控件中的控件綁定到另一個控件。 其中一個原因是您可能希望稍後將它們綁定到外部元素。

或者,使用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> 

,並和兩個參數轉換成你想要的值轉換器。

+0

謝謝丹尼。這工作得很好。但我希望不必硬編碼參數值。我不知道參數需要是一個常量。謝謝! – Doug 2008-11-23 16:14:11

+0

非常感謝,非常樂於助人! – Jacob 2014-09-08 10:09:32

3

雖然我懷疑可能有更好的方法來解決你的問題,但我想我有一個你想要做的答案。 (你沒有提到什麼類型的容器。一個StackPanel例如需要照顧的寬度計算你的。見下面文本框#2)

首先,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> 

下的轉換器。我們在這裏有一個問題..因爲某種原因the ConverterParameter for the Convert methods cannot be a dynamic value。所以我們通過我們在Window's ctor中設置的Converter的公共屬性潛入Textbox Margin。 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。感謝您的鍛鍊:)

0

如果你的文本框是LayoutRoot的直接孩子,只需設置以下屬性在文本

HorizontalAlignment="Stretch" 
5

yes..multi結合對我的作品..其實我試着發送元素作爲convereter參數,但它不接受。這就是爲什麼我將元素作爲值傳遞給轉換器類。

下面

是我的例子..

<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> 

在窗口調整大小,我的第一gridviewcolumn必須被調整大小,而不是另外兩個gridviewcolumns .. 我經過ActualWidth的列表視圖,並且也總gridview的對象作爲元素.. 如果你去轉換代碼...

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 
} 

這個工作對我來說... :)

相關問題