Привязка WPF к ViewModel из отдельной - PullRequest
1 голос
/ 07 августа 2020

Я пытаюсь создать привязку между моей ViewModel и ControlTemplate для кнопки, которая находится в отдельном файле, который вызывает мой View.

Пока ни один из стандартных методов не сработал, и я Не знаете, как указать кнопке ControlTemplate, которую можно вызвать из любого представления (а на самом деле я использую в двух представлениях), использовать ViewModel, прикрепленную к вызывающему ее представлению. Искал часами без решения (ни объяснения, ни примера для экстраполяции). Возможно, я неправильно это формулирую. Я использую Caliburn Micro для MVVM.

ShellViewModel содержит следующее, которое устанавливается, когда мой ShellView / ViewModel активирует View / ViewModel (оболочка остается открытой, другие существуют внутри нее при вызове).

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

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

Нажатие моей кнопки в ShellView корректно обновляет ButtonBkgdBuy и активирует мою BuyViewModel. Сама кнопка не меняет свой цвет и не имеет правильного исходного цвета, установленного по умолчанию в cs. Вот кнопка в 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>

Шаблон находится в отдельном файле и представлен в 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>

Наконец, полная версия файла кнопки, чтобы не пропустить что-то. В данной строке я добавил комментарии до и после

<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>

Спасибо за любую помощь. Я никогда не пробовал использовать такую ​​привязку, и хотя я предполагаю, что это возможно, я не уверен, как это будет называться. Я счастлив прочитать это, если бы я только знал, что искать.

1 Ответ

1 голос
/ 07 августа 2020

Привязка непосредственно к ButtonBkgdBu должна работать при условии, что Button, к которому в настоящее время применяется шаблон, имеет DataContext со свойством publi c ButtonBkgdBuy, которое возвращает Color:

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

Если вы хотите иметь возможность использовать один и тот же шаблон для разных контекстов данных, вам следует либо создать присоединенное свойство и привязать его к нему, либо использовать свойство Tag или любое другое свойство самого Button:

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

Затем вы можете установить свойство, которое вы привязываете в шаблоне для каждого экземпляра 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...