绑定到MVVM中的TextBlock Width属性

时间:2013-02-01 06:28:26

标签: c# wpf mvvm

我的视图中有一个TextBlock控件,其Width取决于Text属性。

我正在寻找一些方法将TextBlocks Width绑定到我的模型中的属性,这将按如下方式工作:

  1. 必须根据Width
  2. 自动完成Text的设置
  3. 在我的按钮中单击我想要检索宽度
  4. 我已经尝试了下面的代码,但如果我没有在视图模型的构造函数中明确设置它,它会将Width保持为0.Tried Mode=OneWayToSourceMode=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());
    }
    

    }

4 个答案:

答案 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,或者使Horizo​​ntalAlignment Left在文本更改时看到ActualWidth更改。

我对您的源代码进行了一些更改。考虑在按钮上使用CommandParameter?看看链接......

WpfApplication10.zip

答案 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;