【问题标题】:Get reference to code-behind class instance from IValueConverter从 IValueConverter 获取对代码隐藏类实例的引用
【发布时间】:2020-10-19 12:57:20
【问题描述】:

我有这个代码:

namespace Test
{
    public partial class SearchField : UserControl
    {
        public SearchStrategy Strategy { get; set; }
        public SearchField() { InitializeComponent(); }
    }

    public class TextToTipConverter : IValueConverter
    {
        public object Convert(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            SearchStrategy Strategy = // How do I get reference to SearchField.Strategy from here?

            return Strategy.parseInput<string> (value.ToString(), (first, inp) => Strategy.tipMap.ContainsKey(first) && inp.Length == 1 ? first + Strategy.tipMap[first] : "", AppResources.GeneralSearchTip);
        }

        public object ConvertBack(object value, Type targetType,
            object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

XAML 中的代码:

<UserControl.Resources>
        <controls:TextToTipConverter x:Key="TextToTip" />
</UserControl.Resources>
...
<TextBox x:Name="Search" Grid.Column="0" Canvas.ZIndex="1" 
                 Style="{StaticResource SearchBoxStyle}" Foreground="{StaticResource PhoneForegroundBrush}" />

<TextBox x:Name="Tip" Grid.Column="0" Canvas.ZIndex="0" IsReadOnly="True"
                 Style="{StaticResource SearchBoxStyle}" Opacity="0.5" Foreground="{StaticResource PhoneAccentBrush}"
                 Text="{Binding ElementName=Search, Converter={StaticResource TextToTip}, Path=Text}" />

SearchFieldSearchStrategy Strategy 有一些我需要从TextToTipConverter 访问的方法和字段。 我怎样才能得到它?

【问题讨论】:

  • 我过去遇到过类似的问题。理想的做法是将您的 SearchStrategy 对象绑定到 ConverterParameter,但这是不可能的,因为 Binding 不是 DependencyObject,因此 ConverterParameter 不可绑定。通过 value 参数将什么类型的对象传递给 Convert() 方法?
  • @RaySaltrelli 我已经更新了帖子并包含了 XAML。

标签: c# reference code-behind windows-phone-8


【解决方案1】:

SearchField.xaml 是视图,SearchField.xaml.cs 是背后的代码。您可以在 msdn 上阅读有关 MVVM、数据绑定和 ViewModel 的信息。 您可以创建一个名为 ViewModel 的类,您将在其上绑定您的数据。例如,想象以下类:

public class SearchViewModel : INotifyPropertyChanged
{
    public string Text { get; set; }
    public SearchStrategy Strategy { get; set; }
}

您的 SearchField.xaml.cs 将是:

public partial class SearchField : UserControl
{
    private SearchViewModel viewModel;

    public SearchField() 
    {
        this.viewModel = new SearchViewModel ();
        this.DataContext = this.viewModel;
    }
}

现在在您的 xaml 中,

TextBox x:Name="Search" Text="{Binding Text}"

将 viewModel 中的数据与 TextBox 绑定 你将能够做到:

TextBox x:Name="Tip" Text="{Binding, Converter={StaticResource TextToTip}, Path=Text}"

在转换器中,名为 value 的参数将是您可以在其上获取属性的视图模型:

SearchViewModel vm = (SearchViewModel) value;
vm.Strategy;
vm.Text

我不知道我是否清楚。

【讨论】:

  • 通知接口 INotifyPropertyChanged 由我的视图模型实现。实际上,当您在文本块中修改属性时,它会自动设置为视图模型中的属性 Text。但是,如果您想在另一个组件设置属性时更改 TextBox,则必须引发 propertyChanged 事件。您可以在 msdn 上找到有关它的信息
  • 是的,我已经读过了,谢谢。编译器实际上要求我在SearchViewModel 上实现PropertyChanged 事件。是的,我确实需要以编程方式更改绑定值并将其反映在 UI 中,因此您提出的解决方案非常好。
【解决方案2】:

我认为与其将提示文本框直接绑定到搜索文本框,不如尝试在搜索文本框和 SearchFieldViewModel 中的属性之间创建双向绑定。这将导致对搜索文本框的更改自动下推到 SearchFieldViewModel。

一旦搜索字符串位于 SearchFieldViewModel 中,您就可以将其与 SearchStrategy 一起捆绑到 TipViewModel 中,并将 TipViewModel 用作您的 Tip 文本框的 DataContext。请参阅下面的代码。

SearchField.xaml

<UserControl x:Class="SilverlightApplication.SearchField"
    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:local="clr-namespace:SilverlightApplication"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <UserControl.Resources>
        <local:TextToTipConverter x:Key="TextToTip" />
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <TextBox x:Name="Search" Grid.Column="0" Canvas.ZIndex="1" Text="{Binding Path=SearchString, Mode=TwoWay}"
                 Style="{StaticResource SearchBoxStyle}" Foreground="{StaticResource PhoneForegroundBrush}" />

        <TextBox x:Name="Tip" Grid.Column="0" Canvas.ZIndex="0" IsReadOnly="True"
                 Style="{StaticResource SearchBoxStyle}" Opacity="0.5" Foreground="{StaticResource PhoneAccentBrush}"
                 Text="{Binding Path=TipViewModel, Converter={StaticResource TextToTip}}"/>
    </Grid>
</UserControl>

SearchField.xaml.cs

public partial class SearchField : UserControl
{
   public SearchField()
   {
       InitializeComponent();

       this.Loaded += (s, e) => this.LayoutRoot.DataContext = new SearchFieldViewModel();
    }
}

SearchFieldViewModel.cs

public class SearchFieldViewModel
{
    public string SearchString { get; set; }
    public SearchStrategy SearchStrategy { get; set; }

    public TipViewModel TipViewModel
    {
        get
        {
            return new TipViewModel
            {
                SearchString = this.SearchString,
                SearchStrategy = this.SearchStrategy
            };
        }
    }
}

TipViewModel.cs

public class TipViewModel
{
    public string SearchString { get; set; }
    public SearchStrategy SearchStrategy { get; set; }
}

TextToTipConverter.cs

public class TextToTipConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        TipViewModel tipViewModel = value as TipViewModel;
        SearchStrategy strategy = tipViewModel.SearchStrategy;
        string searchString = tipViewModel.SearchString;

        return Strategy.parseInput<string>(searchString , (first, inp) => strategy.tipMap.ContainsKey(first) && inp.Length == 1 ? first + strategy.tipMap[first] : "", AppResources.GeneralSearchTip);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

【讨论】:

  • 这和我的回答很相似,也很好(也许更好)。另一种解决方案是使用多转换器进行多绑定。
【解决方案3】:

将您的 SearchStrategy 放入您的 ViewModel 并使用 Binding 传递它。我不知道我是否回答了你的问题,请提供更多信息

【讨论】:

  • 我对 XAML 和 C# 有点陌生,只知道一些绑定的基础知识。我不明白你说的Put your SearchStrategy in your ViewModel and pass it using Binding.是什么意思,你能详细说明一下吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 2012-12-28
  • 2013-03-15
  • 1970-01-01
  • 2011-12-09
  • 1970-01-01
相关资源
最近更新 更多