所以这是我上次在这里提问时提出的某种跟进问题How to Vertically “center” align the multi line text
在最后一次来自答复者的评论:
Exactly that, plus that you should not manipulate UI elements in code, but instead make yourself familiar with MVVM
回答者还使用
EllipseGeometry
和Path
很好地回答了问题。但是,由于我对Path
不太熟悉,所以我试图找到另一种更“适合”我的风格的方式。我发现这是另一种实现方式:
转换器类
public class NoteOctaveConverter : IValueConverter
{
private const double _dotDiameter = 3;
private readonly Thickness _dotMargin = new Thickness(0.25);
private SolidColorBrush _dotFill;
private readonly HorizontalAlignment _dotHzAlign = HorizontalAlignment.Center;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int octave = (int)value;
List<Ellipse> dots = new List<Ellipse>();
StackPanel stack = new StackPanel();
if ((octave > 0 && parameter as string == "TOP") || (octave < 0 && parameter as string == "BOT"))
{
_dotFill = Brushes.Black;
}
else
{
_dotFill = Brushes.Transparent;
}
for (int i = 0; i < Math.Abs(octave); i++)
{
dots.Add(new Ellipse());
dots[i].Width = _dotDiameter;
dots[i].Height = _dotDiameter;
dots[i].Margin = _dotMargin;
dots[i].Fill = _dotFill;
dots[i].HorizontalAlignment = _dotHzAlign;
stack.Children.Add(dots[i]);
}
return stack;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
,这就是我将其呈现给 View 的方式:
<ContentPresenter Grid.Column="1" Grid.Row="2"
Content="{Binding Path=MusicalNotation.Octave, Converter={StaticResource NoteOctaveConverter}, ConverterParameter=BOT, Mode=OneWay}"
HorizontalAlignment="Center" VerticalAlignment="Top"/>
如果答案是“不操作代码中的UI元素”是什么意思(我是MVVM的新手),则为idk,但是从MVVM的角度来说,这种方式*可接受的,因为我想尝试在良好的环境中使用MVVM道路?
*)这种方式=使用
StackPanel
从Converter
中显示一个ContentPresenter
。附加说明:
我之所以使用
ContentPresenter
而不是Path
的原因是,我需要很好地理解自己的工作,因为我可能必须在演示 session 中将其呈现给我的讲师(我不想呈现新的(风险) IF 我有另一种可能的方法,对我来说更舒适)。如果事实证明以我的方式使用
StackPanel
是不好的做法,请告诉我原因是什么。谢谢你。
最佳答案
我建议您在内容演示者内容上使用DataTemplate
<ContentPresenter Content="{Binding X}"/>
<COntentPresenter.ContentTemplate>
<DataTemplate >
<StackPanel>...</StackPanel>
</DataTemplate>
</COntentPresenter.ContentTemplate>
</ContentPresenter/>
显然,您需要在StackPanel内部进行一些动态收集处理-若要完成此操作,您可以阅读Bind Collection to StackPanel。这样的问题已经回答。
关于“从dataConverter返回控件是一种好习惯”:
我怀疑。因为转换器并非旨在返回完整的控件,所以这是数据模板的任务。好吧,它们显然可以但通常用于更简单的任务-一些其他格式或颜色值。当他们创建控件时,他们违反了MVVM和“XAML中的最大UI”原则。在这种情况下,他们这样做毫无优势。更糟糕的是,您很难理解转换方法,而无法获得清晰的XAML和viewmodel逻辑。
关于c# - MVVM的良好做法是在转换器中初始化StackPanel并使用ContentPresenter呈现吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24331312/