我的视图中有一个TextBlock
控件,其Width
取决于Text
属性。
我正在寻找一些方法将TextBlocks Width
绑定到我的模型中的属性,这将按如下方式工作:
Width
Text
的设置
我已经尝试了下面的代码,但如果我没有在视图模型的构造函数中明确设置它,它会将Width
保持为0.Tried Mode=OneWayToSource
和Mode=OneWay
但它没有任何区别,有什么建议吗?
查看:
<Grid>
<TextBlock Text="Some text" Width="{Binding TextWidth,Mode=OneWayToSource}" />
<Button Content="Show Width" Height="30" Width="90" Command="{Binding ShowTextWidth}" />
</Grid>
查看型号:
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private DelegateCommand<object> showTextWidth;
public DelegateCommand<object> ShowTextWidth
{
get { return showTextWidth; }
set { showTextWidth = value; }
}
private double textWidth;
public double TextWidth
{
get { return textWidth; }
set
{
textWidth = value;
OnPropertyChanged("TextWidth");
}
}
public ViewModel()
{
//If I explicitly specify the width it works:
//TextWidth = 100;
ShowTextWidth = new DelegateCommand<object>(ShowWidth);
}
private void ShowWidth(object parameter)
{
MessageBox.Show(TextWidth.ToString());
}
}
答案 0 :(得分:1)
Width是TextBlock上的DependencyProperty。在这种情况下,它是绑定目标,TextWidth是绑定的源。 OneWayToSource似乎是要走的路,你在ViewModel中将TextWidth设置为100,它不会传播到TextBlock上的Width,因为它的OneWayToSource是正确的,Width(Target)然后将TextWidth(Source)设置为Double.NaN,因为OneWayToSource和这就是你看到0 ...
的原因ActualWidth应该像sa_ddam213那样工作,但是当Text更改时,TextBlock也不会在Width(ActualWidth)中增长,因为它跨越了Grid布局的总宽度。将其放在ColumnDefinition中,将Width设置为Auto,或者使HorizontalAlignment Left在文本更改时看到ActualWidth更改。
我对您的源代码进行了一些更改。考虑在按钮上使用CommandParameter?看看链接......
答案 1 :(得分:1)
最终创建了一个受Kent Boogaarts by Maleak启发的附加行为Pushing read-only GUI properties back into ViewModel,无法相信将ActualWidth的值推入视图模型是如此复杂!
答案 2 :(得分:0)
如果你选择一个可以为你处理这个问题的布局面板,你真的不需要设置宽度。
例如。 width = auto的columndefinition随着文本的增长而增长
答案 3 :(得分:0)
要根据包含Text的宽度设置宽度,可以将Width-Property绑定到Text-Property并使用如下转换器:
<TextBlock Width="{Binding RelativeSource={RelativeSource Self}, Path=Text, Converter={StaticResource TextToWidth}}"
您的转换器可能如下所示:
TextBlock tb = new TextBlock();
tb.Text = value.ToString();
tb.Measure(new Size(int.MaxValue, 20)); //20 if there shouldnt be a linebreak
return tb.DesiredSize.Width;