0

モデルにバインドしたいコマンドボタン(入力付き)のリストがあります。ボタンのテキストボックスをどこかにバインドしたいのです(viewmodelを参照)。

次のコードは私が試したものと失敗したものです。モデルにバインディングを設定してから、これをコントロールにバインドすることは(さらに)可能ですか?

言い換えれば、私は愚かな方法で何かをしようとしていますか?

意見:

<ToolBar Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="0" ItemsSource="{Binding SelectedTab.Commands}" Height="34">
    <ToolBar.Resources>
        <DataTemplate DataType="{x:Type model:ZoekCommandButtons}">
            <Button Command="{Binding Command}" ToolTip="{Binding Tooltip}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding Image, Converter={StaticResource ImageConv}}" Height="16" Width="16"></Image>
                    **<TextBox Width="100" Text="{Binding Text}">**
                        <TextBox.InputBindings>
                            <KeyBinding Gesture="Enter" Command="{Binding Command}"></KeyBinding>
                        </TextBox.InputBindings>
                    </TextBox>
                </StackPanel>
            </Button>
        </DataTemplate>
    </ToolBar.Resources>
</ToolBar>

モデル:

    public class ZoekCommandButtons : BaseModel, ICommandItem
    {
        private string _header;
        private string _image;
        private bool _isEnabled;
        private Visibility _isVisible;
        private ICommand _command;
        private string _tooltip;
        private Binding _text;


        public Binding Text
        {
            get { return _text; }
            set { _text = value; OnPropertyChanged("Text"); }
        }
(etc)

ビューモデル:

    Commands.Add(new ZoekCommandButtons()
    {
        Image = "search.png",
        IsEnabled = true,
        **Text = new Binding { RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(UserControl), 1), Path = new PropertyPath("FilterText") },**
        Command = FilterCommand,
        Tooltip = "Zoeken",
        Header = "Zoeken"
    });
4

2 に答える 2

3

まず、ViewModelプロパティとして公開することはお勧めしません。Bindingこの特定のケースでは、ViewModelをネストしているように聞こえますが、そのアプローチの方がはるかに適しMamaViewModelています。つまり、「Commands」プロパティを持つ「」があり、これが「」のコレクションになりCommandButtonViewModelsます。 ..

わかりました、それは言った...あなたはこれを行うことができますが、私はあなたがおそらくすべきではないことを繰り返し述べなければなりませ; 不足しているのは、値を提供するための「バインディングを評価するための何か」です。これがあなたにそれを与えるクラスです:

public static class BindingEvaluator
{
    // need a DP to set the binding to
    private static readonly DependencyProperty PlaceholderProperty = 
        DependencyProperty.RegisterAttached("Placeholder", typeof(object), typeof(DependencyObject), new UIPropertyMetadata(null));

    // Evaluate a binding by attaching it to a dummy object/property and evaluating the property value
    public static object Evaluate(Binding binding)
    {
        var throwaway = new DependencyObject();
        BindingOperations.SetBinding(throwaway, PlaceholderProperty, binding);
        var retVal = throwaway.GetValue(PlaceholderProperty);
        return retVal;
    }
}

それは、ViewModel定義と組み合わせて次のようになります。

public class DontDoThisViewModel
{
    public Binding TextBinding {get; set;}
    public string Text 
    {
        get 
        {
            return BindingEvaluator.Evaluate(TextBinding) as string;
        }
    }
}

動作するはずです...これが私がLINQPadで一緒に投げたテストアプリです:

void Main()
{
    var wnd = new Window() { Title = "My window" };
    var text = new TextBlock();
    text.Text = "Hopefully this shows the window title...";
    text.SetBinding(TextBlock.TextProperty, new Binding("Text"));
    wnd.Content = text;
    var vm = new ViewModel();
    var vmBinding = new Binding("Title");
    vmBinding.Source = wnd;
    vm.TextBinding = vmBinding;
    wnd.DataContext = vm;
    wnd.Show();
}

繰り返しになりますが、これを行わないことを強くお勧めします...しかし、私は興味があったので、方法を考え出す必要がありました。;)

于 2012-11-19T17:27:33.393 に答える
0

Ok。私はまっすぐに考えていませんでした。

モデルのTextプロパティをstringに変更し、このプロパティを使用してコマンドを処理しました。

(どういうわけかモデルにバインディングを設定するといいのですが...)

于 2012-11-19T16:53:39.403 に答える