Wpf 为什么可以';我不能在矩形上使用IMultiValueConverter。宽度?
我需要在ItemsControl中绘制矩形,其宽度由绑定集合中定义的值和集合的最大值计算得出。所以我想我需要使用一个多值转换器来传递项的值和集合的最大值 这种将属性添加到转换器的解决方案效果很好,但当我将视图与VM分离时就不行了 看起来我无法使用多重绑定设置width属性-我的转换器正在被调用并返回正确的值,但我没有看到矩形:Wpf 为什么可以';我不能在矩形上使用IMultiValueConverter。宽度?,wpf,mvvm,converter,ivalueconverter,Wpf,Mvvm,Converter,Ivalueconverter,我需要在ItemsControl中绘制矩形,其宽度由绑定集合中定义的值和集合的最大值计算得出。所以我想我需要使用一个多值转换器来传递项的值和集合的最大值 这种将属性添加到转换器的解决方案效果很好,但当我将视图与VM分离时就不行了 看起来我无法使用多重绑定设置width属性-我的转换器正在被调用并返回正确的值,但我没有看到矩形: <ListBox x:Name="list" ItemsSource="{Binding Companies}"> <ListBox.ItemT
<ListBox x:Name="list" ItemsSource="{Binding Companies}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding CountInvitations}" />
<Rectangle Height="20" Fill="Black">
<Rectangle.Width>
<MultiBinding Converter="{StaticResource myMultiValueConverter}">
<Binding Path="CountInvitations" />
<Binding ElementName="MainLayout" Path="DataContext.MaxCount" />
</MultiBinding>
</Rectangle.Width>
</Rectangle>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
是否无法通过多重绑定设置矩形宽度 是的。这就是为什么它不起作用 问题在于,矩形渲染后会对绑定求值。计算后,TextBlock将删除任何内容元素。我认为文本块将字符串视为“特例”,而不是直接创建子元素来容纳文本。因此,绑定的结果是一个字符串,矩形将从可视树中删除 这是我在一分钟内拼凑的一个简短的演示。首先,用户界面:
<Window x:Class="TextBlockContent.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="525" Width="525">
<UniformGrid Columns="1">
<TextBlock Text="This text is static">
<Rectangle Fill="Red"
Width="150"
Height="150" />
</TextBlock>
<TextBlock Text="{Binding ThisTextIsSetByABinding}">
<Rectangle Fill="Yellow"
Width="150"
Height="150" />
</TextBlock>
<TextBlock Text="{Binding ThisTextIsUpdatedByAButton}">
<Rectangle Fill="Green"
Width="150"
Height="150" />
</TextBlock>
<Button Content="Click to update the last TextBlock"
Command="{Binding}" />
</UniformGrid>
</Window>
(为了节省空间,VM充当ICommand)我们有一个可以更新的文本属性,一个不能更新。现在让我们看看它们如何在UI中呈现
注意,我不需要执行Updateable属性——绑定设置的两个属性都没有矩形。在这里,让我们使用Snoop检查可视化树,看看矩形是否仍然存在:
请注意,只有第一个TextBlock包含矩形。接下来的两个已通过绑定操作删除了内容
所以,是的,可以在矩形宽度上使用多重绑定,但不能这样做。此外,在文本块中抛出矩形有点代码味道
解决方案是使用父容器组合TextBlock和矩形,而不是尝试将TextBlock本身用作容器。将转换器更改为return double可以满足我的要求:
<Window x:Class="TextBlockContent.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="525" Width="525">
<UniformGrid Columns="1">
<TextBlock Text="This text is static">
<Rectangle Fill="Red"
Width="150"
Height="150" />
</TextBlock>
<TextBlock Text="{Binding ThisTextIsSetByABinding}">
<Rectangle Fill="Yellow"
Width="150"
Height="150" />
</TextBlock>
<TextBlock Text="{Binding ThisTextIsUpdatedByAButton}">
<Rectangle Fill="Green"
Width="150"
Height="150" />
</TextBlock>
<Button Content="Click to update the last TextBlock"
Command="{Binding}" />
</UniformGrid>
</Window>
public class ViewModel : INotifyPropertyChanged, ICommand
{
// events
public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler CanExecuteChanged;
// this property is set once prior to the binding being evaluated
public string ThisTextIsSetByABinding { get; set; }
private string _thisTextIsUpdatedByAButton =
"This text is updated by a button";
// this one is updated and so is INPC
public string ThisTextIsUpdatedByAButton
{
get
{
return _thisTextIsUpdatedByAButton;
}
set
{
_thisTextIsUpdatedByAButton = value;
PropertyChanged(this, new
PropertyChangedEventArgs("ThisTextIsUpdatedByAButton"));
}
}
public ViewModel()
{
ThisTextIsSetByABinding = "This text is set by a binding";
}
// ICommand impl
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
ThisTextIsUpdatedByAButton = "Text updated!";
}
}