我想根据容器的宽度设置TextBlock的宽度,减去TextBlock上设置的边距。
这是我的代码
<TextBlock x:Name="txtStatusMessages"
Width="{Binding ElementName=LayoutRoot,Path=ActualWidth }"
TextWrapping="WrapWithOverflow"
Foreground="White"
Margin="5,5,5,5">This is a message
</TextBlock>
除了由于左边距和右边距设置为5而使TextBlock为10个单位太大以外,这种方法很有效。
好的,所以我想......让我们使用转换器。但我不知道如何传递容器控件的ActualWidth(见上图:LayoutRoot)。
我知道如何使用转换器,甚至是带参数的转换器,而不是像......参数ElementName = LayoutRoot,Path = ActualWidth
例如,我无法完成这项工作......
Width="{Binding Converter={StaticResource PositionConverter},
ConverterParameter={Binding ElementName=LayoutRoot,Path=ActualWidth }}"
我希望我已经说清楚了,希望你可以提供帮助,因为Google今晚对我毫无帮助。
TIA!
道格
答案 0 :(得分:13)
你应该使用其他控件作为源,而不是参数。 参数必须是常量,在您的情况下可以是-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>
和转换器将两个参数转换为您想要的值。
答案 1 :(得分:6)
是的..多重绑定对我有用..实际上我试图发送一个元素作为一个convereterparameter,但它不接受。这就是为什么我将元素作为值传递给转换器类。
下面是我的例子..
<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。 我通过了listview的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
}
这对我有用...... :)
答案 2 :(得分:3)
虽然我怀疑可能有更好的方法来解决您的问题,但我认为我对您想要做的事情有一个答案。 (你没有提到你的容器是什么类型。例如,StackPanel负责你的宽度计算。见下面的TextBox#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的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。谢谢你的练习:)
答案 3 :(得分:0)
如果您的文本框是LayoutRoot的直接子项,只需在文本框中设置以下属性
HorizontalAlignment="Stretch"
答案 4 :(得分:0)
根据http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7298ceb5-bf56-47aa-a161-5dd99189408b,如果转换器是从DependencyObject派生的,则可以向自定义转换器添加Dependency属性。
在这种情况下,您甚至可以使用数据绑定将值传递给在XAML中定义转换器(在资源字典中)的属性。