简体   繁体   English

WPF 从单独的 ViewModel 绑定

[英]WPF Binding to ViewModel from separate

I am trying to create a Binding between my ViewModel and a ControlTemplate for a button, which is in a separate file that my View calls.我正在尝试在我的 ViewModel 和一个按钮的 ControlTemplate 之间创建一个绑定,该按钮位于我的 View 调用的单独文件中。

So far none of the standard methods have worked, and I am unsure how to tell the ControlTemplate button, which can be called from any View (and in fact I use in 2 views) to use the ViewModel attached to the View that calls it.到目前为止,没有一个标准方法起作用,我不确定如何告诉 ControlTemplate 按钮,该按钮可以从任何视图(实际上我在 2 个视图中使用)调用,以使用附加到调用它的视图的 ViewModel。 Been searching for hours without a solution (neither an explanation nor example to extrapolate from).一直在寻找几个小时没有解决方案(既没有解释也没有例子可以推断)。 I may not be wording this correctly.我的措辞可能不正确。 I am using Caliburn Micro for MVVM.我正在为 MVVM 使用 Caliburn Micro。

ShellViewModel contains the following, which is set when my ShellView/ViewModel activates a View/ViewModel (Shell stays open, others exist inside of it when called). ShellViewModel 包含以下内容,当我的 ShellView/ViewModel 激活 View/ViewModel 时设置(Shell 保持打开状态,调用时其他存在于其中)。

public void LoadBuy()
    {
        ButtonBkgdBuy = "Blue";
        ActivateItem(BuyViewModel);
    }

private string _buttonBkgdBuy = "Green";
public string ButtonBkgdBuy
{
    get { return _buttonBkgdBuy; }
    set 
    { 
        _buttonBkgdBuy = value;
        NotifyOfPropertyChange(() => ButtonBkgdBuy);
    }
}

Clicking my button in the ShellView correct updates the ButtonBkgdBuy and activates my BuyViewModel.在 ShellView 正确单击我的按钮会更新 ButtonBkgdBuy 并激活我的 BuyViewModel。 The button itself does not change it's color, nor have correct original color set as default in cs.按钮本身不会改变它的颜色,也不会在cs中将正确的原始颜色设置为默认值。 Here is the button in ShellView:这是 ShellView 中的按钮:

<StackPanel>
    <Button Template="{DynamicResource BlackButton}" x:Name="LoadBuy"  Width="238" Margin="15,0,0,0"  FontSize="24" Height="40" Content="Browse Our Selection"/>
</StackPanel>

Template is in separate file, and introduced in App.xaml:模板在单独的文件中,并在 App.xaml 中介绍:

<Application x:Class="Retail_Kiosk.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Retail_Kiosk">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:Bootstrapper x:Key="Bootstrapper" />
                    <Brush x:Key="BorderMain">#700000</Brush>
                    <Brush x:Key="BorderAccent">#7c4599</Brush>
                </ResourceDictionary>
                <ResourceDictionary Source="Templates\ButtonBlack.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Finally, a full version of the button's file to avoid missing something.最后,一个完整版本的按钮文件,以避免遗漏一些东西。 The line in question I have added comments before and after有问题的行我在之前和之后添加了评论

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <ControlTemplate TargetType="{x:Type Button}" x:Key="BlackButton">
        <Button Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualHeight}"
                BorderBrush="{x:Null}" BorderThickness="0"
                Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}"
                >
            <Button.Effect>
                <DropShadowEffect BlurRadius="12" Color="Gray" Direction="270" Opacity=".8" ShadowDepth="3" />
            </Button.Effect>

            <Button.Template>
                <ControlTemplate TargetType="Button">
                    <Grid Width="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=ActualWidth}"
                          Height="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=ActualHeight}">
                        <Border x:Name="MainBorder" CornerRadius="3" Grid.ColumnSpan="2" Margin="0,0,4,4" BorderBrush="Black" BorderThickness="1">
                            <Border.Background>
                                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                                    <GradientStop Color="#FF5E5E5E" Offset="0" />
<!-- BEGIN: This is the Gradient that should be supplied a color, I know Binding isn't a full option, it's just my resting default. -->
<!-- If I add a color directly, the button has the color.  Code is correct.  If I try any of my binding attempts, binding fails and no color.-->
                                    <GradientStop Color="{Binding}" Offset="1" />
<!-- END -->
                                </LinearGradientBrush>
                            </Border.Background>
                            <Grid >
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>

                                <Border CornerRadius="2" Margin="0" BorderBrush="LightGray" BorderThickness="0,1,0,0" Grid.ColumnSpan="2" Grid.RowSpan="2" />

                                <Grid Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto" />
                                    </Grid.RowDefinitions>

                                    <TextBlock x:Name="Title" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content, FallbackValue='Button'}" 
                                                Grid.Column="1" Grid.Row="0" FontFamily="Calibri" FontWeight="Bold" 
                                                FontSize="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FontSize}" 
                                                Foreground="White" Margin="10,0,0,0" Padding="0,0,0,0"/>
                                </Grid>
                            </Grid>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="MainBorder" Property="Background">
                                <Setter.Value>
                                    <LinearGradientBrush>
                                        <GradientStop Color="#000000" Offset="0" />
                                        <GradientStop Color="Aqua" Offset="1" />

                                    </LinearGradientBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="MainBorder" Property="Background">
                                <Setter.Value>
                                    <LinearGradientBrush>
                                            <GradientStop Color="#000000" Offset="0" />
                                            <GradientStop Color="#7f10b3" Offset="1" />
                                    </LinearGradientBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Button.Template>
        </Button>
    </ControlTemplate>
</ResourceDictionary>

Thank you for any help.感谢您的任何帮助。 I have never tried a binding like this, and while I assume possible, am not sure what this would be called.我从未尝试过这样的绑定,虽然我认为可能,但不确定这会被称为什么。 I'm happy to read up on it, if only I knew what to search.我很高兴阅读它,只要我知道要搜索什么。

Binding directly to ButtonBkgdBu should work provided that the Button to which the template is currently applied to has a DataContext with a public ButtonBkgdBuy property that returns a Color :直接绑定到ButtonBkgdBu应该可以工作,前提是模板当前应用到的Button有一个DataContext和一个返回Color的公共ButtonBkgdBuy属性:

<GradientStop Color="{Binding ButtonBkgdBuy}" Offset="1" />

If you want to be able to use the same template for different data contexts, you should either create an attached property and bind to this one or use the Tag property or any other property of the Button itself:如果您希望能够为不同的数据上下文使用相同的模板,您应该创建一个附加属性并绑定到该属性,或者使用Tag属性或Button本身的任何其他属性:

<GradientStop Color="{Binding Tag, RelativeSource={RelativeSource AncestorType=Button}}" Offset="1" />

You can then set the property that you bind to in the template on each Button instance:然后,您可以在每个Button实例的模板中设置您绑定到的属性:

<StackPanel>
    <Button Template="{DynamicResource BlackButton}"
            Tag="Green"
            x:Name="LoadBuy"  Width="238" Margin="15,0,0,0"  FontSize="24" Height="40" Content="Browse Our Selection"/>
</StackPanel>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM