首页 > 解决方案 > UWP+Prism MVVM - 如何通过 XAML 设置视图模型属性的值?

问题描述

我在视图模型中有一个属性,我希望能够通过 XAML 设置它,但我不知道该怎么做。我有一个非常基本的用户控件(包含项目列表),其中两个将放置在页面上,我希望能够将一个设置为“源”(由枚举定义),一个设置为成为“目标”。

[下面的代码已经被删减了很多,如果我不小心犯了一些错误或遗漏了一些东西,我们深表歉意。]

我的枚举是:

public enum ConversionSide
{
    Source, // Convert something FROM whatever is here.
    Target  // Convert something TO whatever is here.
}

我有一个看起来像这样的页面:

<Page
    x:Class="MyApp.Views.ConverterPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:models="using:MyApp.Models"
    xmlns:my="using:MyApp.Controls"
    xmlns:prismMvvm="using:Prism.Windows.Mvvm"
    prismMvvm:ViewModelLocator.AutoWireViewModel="True"
    Style="{StaticResource PageStyle}"
    mc:Ignorable="d">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <my:SelectorPage Name="SourceSelector" Grid.Column="0" />
        <my:SelectorPage Name="TargetSelector" Grid.Column="1" />
    </Grid>

</Page>

...其中 SelectorPage 是一个用户控件(我将其称为“页面”以使 Prism AutoWire 工作,但这不是这里的问题),其中包含一个看起来像这样的项目列表(一切正常)...

<UserControl
    x:Class="MyApp.Controls.SelectorPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:models="using:MyApp.Models"
    xmlns:my="using:MyApp.Controls"
    xmlns:prismMvvm="using:Prism.Windows.Mvvm"
    prismMvvm:ViewModelLocator.AutoWireViewModel="True"
    mc:Ignorable="d">

    <ListView
        Grid.Column="0"
        ItemsSource="{x:Bind ViewModel.MyList, Mode=OneWay}"
        SelectedItem="{x:Bind ViewModel.MySelectedItem, Mode=TwoWay}">
        <ListView.Header>
            <TextBlock Margin="0,8,0,8" HorizontalAlignment="Center" FontStyle="Italic" Text="Header Text" />
        </ListView.Header>
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="models:MyListItem">
                <my:MyListItemTemplate />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</UserControl>

..后面的代码为...

public sealed partial class SelectorPage : UserControl
{
    private SelectorViewModel ViewModel => DataContext as SelectorViewModel;

    public SelectorPage()
    {
        this.InitializeComponent();
    }
}

SelectorViewModel 看起来像这样......

public class SelectorViewModel : ViewModelBase
{
    private ConversionSide _side;

    public ConversionSide Side
    {
        get { return _side; }
        set { SetProperty(ref _side, value); }
    }

    // Many lines have been omitted for 'clarity'.
}

我希望能够像这样在 XAML 中设置 SelectorViewModel 的 Side 属性...

<my:SelectorPage Name="SourceSelector" Grid.Column="0" Side="Source" />
<my:SelectorPage Name="TargetSelector" Grid.Column="1" Side="Target" />

(一旦设置了 Side,我不希望它永远改变。)

我怎样才能做到这一点?

我已经研究过使用依赖属性,但我无法让它更改 SelectorViewModel 中的属性。当我在 SelectorPage 中添加一个时,它在 XAML 中可见,我可以设置它,但它实际上并没有做任何事情,所以我可能没有正确使用它。在视图模型中放置依赖属性对我来说听起来不对,但我可能是错的。我浏览了网络 - Microsoft 文档、博客、文章、堆栈溢出等 - 但我找不到任何可以很好地解释事情的东西,让我弄清楚我应该做什么。我发现的著作似乎完全是关于从绑定属性中获取信息的——我同意——但我所追求的是从 XAML中设置一个属性。

任何人都可以给我任何线索吗?我不知道我是否离得到我想要的东西只有一小步,或者我是否在数英里之外。

标签: c#wpfxamluwpprism

解决方案


这会将控件的Side属性设置为:SelectorPageSource

视图通过双向绑定设置视图模型的属性。例如,以下TextBox设置当您更改文本时string调用的视图模型的属性:TestTextBox

<TextBox Text="{Binding Test, Mode=TwoWay}" />

因此,从视图设置视图模型的属性通常适用于处理某种输入的控件。源属性的任何默认值都应该在视图模型中定义:

private ConversionSide _side = ConversionSide.Source;

您不应该在视图中定义默认值。


推荐阅读